Variables & Data Types
What Are Variables?
A variable is a named container that stores a value in your program’s memory. Think of it as a labeled box where you can put data, retrieve it later, and even change what is inside. In Dart, every variable has a type that determines what kind of data it can hold.
Declaring a Variable
void main() {
String name = 'Edrees';
int age = 28;
double height = 1.78;
bool isStudent = true;
print(name); // Edrees
print(age); // 28
print(height); // 1.78
print(isStudent); // true
}
Type Annotations vs Type Inference
Dart is a statically typed language, meaning every variable has a type. However, you do not always need to write the type explicitly. Dart can infer the type from the value you assign.
Explicit Type Annotation
You write the type yourself before the variable name:
Explicit Types
String city = 'Riyadh';
int population = 7500000;
double area = 1798.0;
bool isCapital = true;
Type Inference with var
The var keyword lets Dart figure out the type automatically from the assigned value. Once assigned, the type is fixed and cannot change.
Using var
var name = 'Ahmed'; // Dart infers String
var age = 25; // Dart infers int
var score = 95.5; // Dart infers double
var passed = true; // Dart infers bool
// name = 42; // ERROR! name is a String, cannot assign int
var does not show the type, the variable is still statically typed. Dart infers the type at compile time, not at runtime. This is different from dynamically typed languages like JavaScript.The dynamic Keyword
If you truly want a variable that can hold any type and change types later, use dynamic. However, this is generally discouraged because you lose type safety.
Using dynamic
dynamic anything = 'Hello';
print(anything); // Hello
print(anything.runtimeType); // String
anything = 42;
print(anything); // 42
print(anything.runtimeType); // int
anything = true;
print(anything); // true
print(anything.runtimeType); // bool
dynamic unless absolutely necessary. It bypasses Dart’s type system, meaning errors that would normally be caught at compile time will only appear at runtime. Use specific types or var instead.Core Data Types in Dart
Dart has several built-in data types. Here are the most important ones:
1. int -- Whole Numbers
Integers are numbers without a decimal point. They can be positive, negative, or zero.
Integer Examples
int age = 30;
int temperature = -5;
int hexValue = 0xFF; // 255 in hexadecimal
int bigNumber = 1000000;
print(age); // 30
print(hexValue); // 255
2. double -- Decimal Numbers
Doubles are numbers with a decimal point, used for fractional values.
Double Examples
double pi = 3.14159;
double price = 29.99;
double negative = -0.5;
double scientific = 1.5e3; // 1500.0
print(pi); // 3.14159
print(scientific); // 1500.0
3. num -- Number (int or double)
The num type is the parent type of both int and double. Use it when a variable could be either.
Using num
num score = 100; // int value
score = 99.5; // now a double value -- both are valid
print(score); // 99.5
4. String -- Text
Strings represent text. You can use single quotes or double quotes.
String Examples
String firstName = 'Edrees';
String lastName = "Salih";
String fullName = '$firstName $lastName';
print(fullName); // Edrees Salih
5. bool -- True or False
Booleans hold only two values: true or false. They are used for conditions and logic.
Boolean Examples
bool isLoggedIn = false;
bool hasPermission = true;
bool isAdult = (age >= 18); // true if age is 18 or more
print(isAdult); // true
6. List -- Ordered Collection
Lists hold an ordered collection of items (like arrays in other languages).
List Preview
List<String> fruits = ['Apple', 'Banana', 'Orange'];
List<int> numbers = [1, 2, 3, 4, 5];
print(fruits[0]); // Apple
print(numbers.length); // 5
7. Map -- Key-Value Pairs
Maps store data as key-value pairs (like dictionaries or objects in other languages).
Map Preview
Map<String, int> ages = {
'Ahmed': 25,
'Sara': 30,
'Ali': 22,
};
print(ages['Ahmed']); // 25
Constants: final and const
When a value should never change after being set, use final or const.
final -- Set Once at Runtime
A final variable can only be set once. Its value is determined at runtime.
Using final
final String name = 'Edrees';
// name = 'Ahmed'; // ERROR! Cannot change a final variable
final now = DateTime.now(); // Value set at runtime
print(now);
const -- Compile-Time Constant
A const variable must be known at compile time. It is more restrictive than final.
Using const
const double pi = 3.14159;
const int maxRetries = 3;
// const now = DateTime.now(); // ERROR! Not a compile-time constant
print(pi); // 3.14159
print(maxRetries); // 3
const when the value is truly a constant known before the program runs (like pi or configuration values). Use final when the value is set once but determined at runtime (like the current date/time or user input).Late Variables
The late keyword tells Dart that a variable will be initialized later, before it is used. This is useful when you cannot assign a value at declaration time.
Using late
late String description;
void main() {
// Some logic first...
description = 'This is set later';
print(description); // This is set later
}
late variable before initializing it, Dart will throw a LateInitializationError at runtime. Always make sure to assign a value before reading it.Type Checking and Casting
Dart provides operators to check and convert types at runtime:
Type Checking with is and as
void main() {
var value = 42;
// Type checking with 'is'
if (value is int) {
print('It is an integer!'); // This prints
}
if (value is! String) {
print('It is NOT a string!'); // This prints
}
// Type casting with 'as'
num number = 3.14;
double decimal = number as double;
print(decimal); // 3.14
}
Summary
Here is a quick reference of what we covered:
var-- Type inferred, fixed after assignmentdynamic-- Can change types (avoid when possible)int,double,num-- NumbersString-- Textbool-- True/falseList,Map-- Collections (covered later in detail)final-- Set once at runtimeconst-- Compile-time constantlate-- Initialized later before useis/as-- Type checking and casting
Practice Exercise
Open DartPad and create a small program that declares variables for a user profile: name (String), age (int), height (double), isActive (bool). Use both explicit types and var. Try creating a final variable for the user’s registration date and a const for the maximum allowed age. Print all values using string interpolation.