Variables & Built-in Data Types
A comprehensive guide to Dart's type system, variables, and collection types.
Primitive Types Overview
Dart provides several built-in types that cover most use cases:
| Type | Description | Example |
|---|---|---|
String | Textual data | 'Hello' |
int | 64-bit integers | 42 |
double | 64-bit floating-point | 3.14 |
bool | True or false | true |
List | Ordered collection | [1, 2, 3] |
Map | Key-value pairs | {'a': 1} |
Set | Unique unordered items | {1, 2, 3} |
Strings
Strings in Dart are UTF-16 encoded. You can use single or double quotes:
strings.dart
// Both are valid
var name = 'Dart';
var greeting = "Hello, Dart!";
// Multi-line strings
var paragraph = '''
This is a
multi-line string in Dart.
''';
// String interpolation
var version = 3;
print('Dart $version is great'); // Dart 3 is great
print('${name.toUpperCase()}!'); // DART!
// Raw strings (no escape processing)
var path = r'C:\Users\file.txt';
Numbers: int and double
numbers.dart
var age = 25; // int
var pi = 3.14159; // double
var precise = 2.0; // double (even without decimal part)
// Type conversions
var intToDouble = pi.toInt(); // 3
var doubleToInt = age.toDouble(); // 25.0
var parsed = int.parse('42'); // 42
var formatted = pi.toStringAsFixed(2); // '3.14'
⚠️ Integer Division
In Dart,
5 / 2 returns 2.5 (a double). Use ~/ for integer division: 5 ~/ 2 returns 2.
Booleans
booleans.dart
var isActive = true;
var isLoggedIn = false;
// Dart has strict boolean checking
// Only `true` is truthy — no implicit conversion
var value = 1;
// if (value) { } // ❌ ERROR: int is not bool
if (value > 0) { } // ✅ Correct
Collection Literals vs Constructors
Prefer collection literals ([], {}, {}) over named constructors. They're more concise and the Dart analyzer recommends them:
collection_literals.dart
// ✅ Preferred: collection literals
var list = [1, 2, 3];
var map = {'key': 'value'};
var set = {1, 2, 3};
// ⚠️ Also valid but verbose
var list = List.filled(3, 0);
var map = Map<String, String>();
Common List Operations
Master these list operations — you'll use them in every Dart and Flutter project:
| Operation | Method | Returns |
|---|---|---|
| Transform | .map() | New lazy iterable |
| Filter | .where() | New lazy iterable |
| Reduce | .fold() | Single value |
| Sort | .sort() | Void (modifies in-place) |
| Search | .firstWhere() | Single element or throws |
| Check | .every() / .any() | bool |
Lists
Ordered, indexable collections. Dart 3 has both legacy List and fixed-length List:
lists.dart
// Growable list
var fruits = [‘Apple’, ‘Banana’, ‘Cherry’];
fruits.add('Date');
fruits.removeAt(1);
// List operations
print(fruits.length); // 3
print(fruits[0]); // Apple
print(fruits.contains('Date')); // true
// Spread operator
var more = [...fruits, 'Elderberry'];
// List properties
var numbers = [3, 1, 4, 1, 5];
numbers.sort();
print(numbers); // [1, 1, 3, 4, 5]
// Map and where
var doubled = numbers.map((n) => n * 2).toList();
var evens = numbers.where((n) => n % 2 == 0).toList();
Maps
Key-value pairs, similar to dictionaries or hash maps in other languages:
maps.dart
var user = {
'name': 'Alice',
'age': 28,
'email': '[email protected]',
};
// Access values
print(user['name']); // Alice
// Add / update entries
user['role'] = 'admin';
user['age'] = 29;
// Check key existence
if (user.containsKey('email')) {
print('Email exists');
}
// Iterate
user.forEach((key, value) {
print('$key: $value');
});
Sets
Unordered collections of unique elements:
sets.dart
var tags = {'dart', 'flutter', 'mobile'};
tags.add('web');
tags.add('dart'); // Duplicate ignored
print(tags.length); // 4
// Set operations
var a = {1, 2, 3};
var b = {2, 3, 4};
print(a.union(b)); // {1, 2, 3, 4}
print(a.intersection(b)); // {2, 3}
print(a.difference(b)); // {1}
Type Inference: var, final, const
| Keyword | Mutable? | Runtime vs Compile-time | Use When |
|---|---|---|---|
var | Yes | Runtime type | Value will change |
final | No | Runtime (set once) | Value determined at runtime |
const | No | Compile-time constant | Value known at compile time |
type_inference.dart
// var — type inferred, mutable
var name = 'Alice';
name = 'Bob'; // ✅ Allowed
// final — type inferred, immutable (set once)
final timestamp = DateTime.now();
// timestamp = DateTime.now(); // ❌ ERROR
// const — compile-time constant
const maxRetries = 3;
const appName = 'dftacademy';
// maxRetries = 5; // ❌ ERROR
💡 Best Practice
Prefer
final over var when the variable won't be reassigned. Use const for values known at compile time.
Real-World Example: Shopping Cart
Modeling an e-commerce cart using Dart's data types:
shopping_cart.dart
void main() {
// Cart item as a Map
var item = {
'id': 1001,
'name': 'Wireless Mouse',
'price': 29.99,
'quantity': 2,
'inStock': true,
'tags': {'electronics', 'peripheral'},
};
// Cart as a list of items
var cart = <Map<String, dynamic>>[item];
// Calculate totals
var subtotal = 0.0;
for (var cartItem in cart) {
var price = cartItem['price'] as double;
var qty = cartItem['quantity'] as int;
subtotal += price * qty;
}
print('Cart items: ${cart.length}');
print('Subtotal: \$${subtotal.toStringAsFixed(2)}');
print('Item tags: ${item['tags']}');
}
Summary
- Dart has rich built-in types:
String,int,double,bool,List,Map,Set - Use
var,final, andconstfor variable declarations final= run-time constant;const= compile-time constant- Collections support powerful methods:
map,where,reduce
🚀 Next Step
Continue to Control Flow & Functions to learn about conditionals, loops, and function syntax.