Variables and Types
Variables in Dart
Variables are containers for storing data values. Dart is a statically typed language with type inference, meaning you can declare variables with or without explicit types.
Variable Declaration
Using var
The var keyword lets Dart infer the type:
var name = 'Alice'; // String
var age = 25; // int
var height = 5.8; // double
var isStudent = true; // boolOnce assigned, the type is fixed:
var count = 10;
// count = 'ten'; // Error: A value of type 'String' can't be assigned to a variable of type 'int'Explicit Type Declaration
You can explicitly specify the type:
String name = 'Bob';
int age = 30;
double price = 19.99;
bool isActive = false;Dynamic Type
Use dynamic when the type can change:
dynamic value = 42;
value = 'Now a string'; // OK
value = true; // OK⚠️ Warning: Avoid dynamic when possible, as it bypasses type safety.
Final and Const
final
A final variable can be set only once:
final String city = 'New York';
// city = 'Boston'; // Error: Can't assign to final variable
final currentTime = DateTime.now(); // Set at runtimeconst
A const variable is a compile-time constant:
const double pi = 3.14159;
const int maxUsers = 100;
// const now = DateTime.now(); // Error: Must be compile-time constantDifference Between final and const
final list1 = [1, 2, 3];
const list2 = [1, 2, 3];
list1.add(4); // OK: The list itself can be modified
// list2.add(4); // Error: Cannot modify const list
// final is set at runtime
final time1 = DateTime.now();
// const must be known at compile time
const time2 = DateTime.now(); // Error!Built-in Types
1. Numbers
int
Integer values (64-bit, -2^63 to 2^63-1):
int score = 95;
int hexValue = 0xFF;
int negativeNum = -42;double
64-bit floating-point numbers:
double temperature = 36.6;
double price = 99.99;
double scientific = 1.42e5; // 142000.0num
Parent type of both int and double:
num value1 = 10; // int
num value2 = 10.5; // double2. Strings
Strings represent sequences of characters:
String greeting = 'Hello';
String message = "Welcome";
String multiline = '''
This is a
multi-line
string
''';3. Booleans
Boolean values are true or false:
bool isLoggedIn = true;
bool hasPermission = false;4. Lists (Arrays)
Ordered collections of objects:
List<int> numbers = [1, 2, 3, 4, 5];
var fruits = ['apple', 'banana', 'orange'];
// Access elements
print(fruits[0]); // apple
// Modify
fruits.add('grape');
fruits[1] = 'mango';5. Sets
Unordered collections of unique items:
Set<String> colors = {'red', 'green', 'blue'};
var numbers = {1, 2, 3, 3, 4}; // {1, 2, 3, 4} - duplicates removed
colors.add('yellow');
colors.remove('red');6. Maps
Key-value pairs:
Map<String, int> ages = {
'Alice': 25,
'Bob': 30,
'Charlie': 35,
};
// Access values
print(ages['Alice']); // 25
// Add/modify
ages['David'] = 28;
ages['Alice'] = 26;7. Runes
Unicode code points of a string:
var heart = '\u2665'; // ♥
var smiley = '\u{1F600}'; // 😀
Runes input = Runes('\u2665 \u{1F600}');
print(String.fromCharCodes(input)); // ♥ 😀8. Symbols
Identifiers used in reflection:
Symbol sym = #mySymbol;Type Checking and Casting
Type Checking with is
var value = 42;
if (value is int) {
print('It\'s an integer');
}
if (value is! String) {
print('It\'s not a string');
}Type Casting with as
dynamic obj = 'Hello';
String str = obj as String; // Cast to String
// Safe casting
if (obj is String) {
String str = obj; // No cast needed, type promotion
}Default Values
Uninitialized variables have a default value of null:
int? count;
print(count); // null
String? name;
print(name); // nullLate Variables
Use late for variables that will be initialized later:
late String description;
void initialize() {
description = 'Initialized later';
}
void main() {
initialize();
print(description); // OK
}Type Inference
Dart can infer types from context:
var numbers = [1, 2, 3]; // List<int>
var map = {'key': 'value'}; // Map<String, String>
// Generic type inference
var list = <String>[]; // List<String>Best Practices
- Prefer
varor explicit types overdynamic - Use
finalfor variables that won't change - Use
constfor compile-time constants - Be explicit with types in public APIs
- Use type inference for local variables when the type is obvious
Examples
Complete Example
void main() {
// Basic types
var name = 'Alice';
int age = 25;
double height = 5.8;
bool isStudent = true;
// Collections
List<String> hobbies = ['reading', 'coding', 'gaming'];
Map<String, dynamic> person = {
'name': name,
'age': age,
'hobbies': hobbies,
};
// Constants
const double pi = 3.14159;
final currentDate = DateTime.now();
// Print information
print('Name: $name');
print('Age: $age');
print('Height: $height meters');
print('Is student: $isStudent');
print('Hobbies: ${hobbies.join(', ')}');
print('Person: $person');
print('Pi: $pi');
print('Date: $currentDate');
}Next Steps
Now that you understand variables and types, let's explore: