Introduction
Dart is a client-optimized programming language developed by Google, primarily used for building Flutter mobile apps, web applications, and server-side applications. Known for its clean syntax, strong typing system, and excellent performance, Dart combines object-oriented programming with modern language features like null safety, async/await, and powerful type inference. This cheatsheet covers fundamental syntax, data types, and core concepts essential for Dart development.
Core Language Concepts
Program Structure
// Main entry point
void main() {
print('Hello, Dart!');
}
// Import statements
import 'dart:core';
import 'dart:io';
import 'package:flutter/material.dart';
// Library declaration
library my_library;
Comments
// Single-line comment
/*
Multi-line comment
Can span multiple lines
*/
/// Documentation comment
/// Used for generating API docs
Variables & Constants
// Variable declaration
var name = 'John'; // Type inferred
String name = 'John'; // Explicit type
late String description; // Late initialization
// Constants
const pi = 3.14159; // Compile-time constant
final timestamp = DateTime.now(); // Runtime constant
// Nullable variables
String? nullable; // Can be null
String nonNullable = 'value'; // Cannot be null
Data Types & Type System
Primitive Types
Numbers
// Integers
int age = 25;
int hexValue = 0xFF; // Hexadecimal
int binary = 0b1010; // Binary
// Doubles
double price = 19.99;
double scientific = 1.42e5; // Scientific notation
// Parsing
int parsed = int.parse('42');
double parsed2 = double.parse('3.14');
Strings
// String declaration
String single = 'Single quotes';
String double = "Double quotes";
String multiline = '''
Multi-line
string content
''';
// String interpolation
String name = 'Dart';
String message = 'Hello, $name!';
String expression = 'Result: ${2 + 3}';
// Raw strings
String rawString = r'No interpolation: $name';
// String methods
String text = 'Hello World';
print(text.length); // 11
print(text.toUpperCase()); // HELLO WORLD
print(text.substring(0, 5)); // Hello
print(text.contains('World')); // true
print(text.split(' ')); // ['Hello', 'World']
Booleans
bool isActive = true;
bool isComplete = false;
// Boolean operations
bool result = true && false; // AND
bool result2 = true || false; // OR
bool result3 = !true; // NOT
Collection Types
Lists
// List declaration
List<int> numbers = [1, 2, 3, 4, 5];
var fruits = ['apple', 'banana', 'orange'];
List<String> emptyList = [];
// List operations
numbers.add(6); // Add element
numbers.addAll([7, 8]); // Add multiple
numbers.insert(0, 0); // Insert at index
numbers.remove(3); // Remove by value
numbers.removeAt(0); // Remove by index
// List properties and methods
print(numbers.length); // Size
print(numbers.isEmpty); // Check if empty
print(numbers.first); // First element
print(numbers.last); // Last element
print(numbers.contains(5)); // Check contains
// List iteration
for (int num in numbers) {
print(num);
}
// List methods
var doubled = numbers.map((n) => n * 2).toList();
var filtered = numbers.where((n) => n > 3).toList();
var sum = numbers.reduce((a, b) => a + b);
Sets
// Set declaration
Set<String> countries = {'USA', 'Canada', 'Mexico'};
var uniqueNumbers = <int>{1, 2, 3, 4, 5};
// Set operations
countries.add('Brazil');
countries.addAll(['Argentina', 'Chile']);
countries.remove('Mexico');
// Set methods
var set1 = {1, 2, 3};
var set2 = {3, 4, 5};
var union = set1.union(set2); // {1, 2, 3, 4, 5}
var intersection = set1.intersection(set2); // {3}
var difference = set1.difference(set2); // {1, 2}
Maps
// Map declaration
Map<String, int> scores = {
'Alice': 85,
'Bob': 92,
'Charlie': 78
};
var capitals = <String, String>{
'USA': 'Washington',
'France': 'Paris',
'Japan': 'Tokyo'
};
// Map operations
scores['David'] = 88; // Add/update
scores.remove('Charlie'); // Remove
// Map properties and methods
print(scores.keys); // Get all keys
print(scores.values); // Get all values
print(scores.length); // Size
print(scores.containsKey('Alice')); // Check key exists
// Map iteration
scores.forEach((name, score) {
print('$name: $score');
});
for (var entry in scores.entries) {
print('${entry.key}: ${entry.value}');
}
Operators & Expressions
Arithmetic Operators
int a = 10, b = 3;
print(a + b); // Addition: 13
print(a - b); // Subtraction: 7
print(a * b); // Multiplication: 30
print(a / b); // Division: 3.333...
print(a ~/ b); // Integer division: 3
print(a % b); // Modulo: 1
// Increment/Decrement
a++; // Post-increment
++a; // Pre-increment
a--; // Post-decrement
--a; // Pre-decrement
Comparison Operators
int x = 5, y = 10;
print(x == y); // Equal: false
print(x != y); // Not equal: true
print(x < y); // Less than: true
print(x <= y); // Less than or equal: true
print(x > y); // Greater than: false
print(x >= y); // Greater than or equal: false
Logical Operators
bool p = true, q = false;
print(p && q); // AND: false
print(p || q); // OR: true
print(!p); // NOT: false
Assignment Operators
int num = 10;
num += 5; // num = num + 5
num -= 3; // num = num - 3
num *= 2; // num = num * 2
num ~/= 4; // num = num ~/ 4
// Null-aware assignment
String? name;
name ??= 'Default'; // Assign only if null
Null Safety Operators
String? nullable;
// Null-aware access
int? length = nullable?.length;
// Null coalescing
String value = nullable ?? 'default';
// Null assertion (use with caution)
String definitelyNotNull = nullable!;
// Cascade operator
var list = <int>[]
..add(1)
..add(2)
..add(3);
Control Flow Structures
Conditional Statements
// If-else
int score = 85;
if (score >= 90) {
print('A grade');
} else if (score >= 80) {
print('B grade');
} else if (score >= 70) {
print('C grade');
} else {
print('Need improvement');
}
// Ternary operator
String result = score >= 60 ? 'Pass' : 'Fail';
// Switch statement
String day = 'Monday';
switch (day) {
case 'Monday':
case 'Tuesday':
print('Weekday');
break;
case 'Saturday':
case 'Sunday':
print('Weekend');
break;
default:
print('Unknown day');
}
Loops
// For loop
for (int i = 0; i < 5; i++) {
print('Count: $i');
}
// For-in loop
var fruits = ['apple', 'banana', 'orange'];
for (String fruit in fruits) {
print(fruit);
}
// While loop
int count = 0;
while (count < 3) {
print('While: $count');
count++;
}
// Do-while loop
int num = 0;
do {
print('Do-while: $num');
num++;
} while (num < 3);
// Break and continue
for (int i = 0; i < 10; i++) {
if (i == 3) continue; // Skip iteration
if (i == 7) break; // Exit loop
print(i);
}
Functions & Methods
Function Declaration
// Basic function
void greet(String name) {
print('Hello, $name!');
}
// Function with return value
int add(int a, int b) {
return a + b;
}
// Arrow function (single expression)
int multiply(int a, int b) => a * b;
// Optional parameters
void introduce(String name, [int? age]) {
print('Name: $name');
if (age != null) print('Age: $age');
}
// Named parameters
void createUser({required String name, int age = 18}) {
print('User: $name, Age: $age');
}
// Function as variable
var calculator = (int a, int b) => a + b;
print(calculator(5, 3)); // 8
Higher-Order Functions
// Function taking function as parameter
void processNumbers(List<int> numbers, Function(int) processor) {
for (int num in numbers) {
processor(num);
}
}
// Usage
processNumbers([1, 2, 3], (num) => print(num * 2));
// Anonymous functions
var list = [1, 2, 3, 4, 5];
var squared = list.map((x) => x * x).toList();
var evens = list.where((x) => x % 2 == 0).toList();
Object-Oriented Programming Basics
Classes and Objects
// Class definition
class Person {
// Properties
String name;
int age;
// Constructor
Person(this.name, this.age);
// Named constructor
Person.baby(this.name) : age = 0;
// Methods
void introduce() {
print('Hi, I\'m $name and I\'m $age years old.');
}
// Getter
String get info => '$name ($age)';
// Setter
set updateAge(int newAge) {
if (newAge >= 0) age = newAge;
}
}
// Creating objects
var person1 = Person('Alice', 25);
var baby = Person.baby('Bob');
person1.introduce(); // Hi, I'm Alice and I'm 25 years old.
print(person1.info); // Alice (25)
Inheritance
// Base class
class Animal {
String name;
Animal(this.name);
void makeSound() {
print('$name makes a sound');
}
}
// Derived class
class Dog extends Animal {
String breed;
Dog(String name, this.breed) : super(name);
@override
void makeSound() {
print('$name barks');
}
void wagTail() {
print('$name wags tail');
}
}
// Usage
var dog = Dog('Buddy', 'Golden Retriever');
dog.makeSound(); // Buddy barks
dog.wagTail(); // Buddy wags tail
Error Handling & Exceptions
Try-Catch Blocks
// Basic exception handling
try {
int result = 10 ~/ 0; // Integer division by zero
} catch (e) {
print('Error occurred: $e');
}
// Specific exception types
try {
var value = int.parse('abc');
} on FormatException catch (e) {
print('Format error: $e');
} catch (e) {
print('Other error: $e');
} finally {
print('Cleanup code here');
}
// Throwing exceptions
void validateAge(int age) {
if (age < 0) {
throw ArgumentError('Age cannot be negative');
}
}
// Custom exceptions
class CustomException implements Exception {
final String message;
CustomException(this.message);
@override
String toString() => 'CustomException: $message';
}
Null Safety Deep Dive
Null Safety Features
// Non-nullable by default
String name = 'Dart'; // Cannot be null
String? nickname; // Can be null
// Null-aware operators
String? getText() => null;
// Safe access
int? length = getText()?.length;
// Null coalescing
String display = getText() ?? 'No text';
// Null assertion (dangerous)
String definite = getText()!; // Throws if null
// Late variables
late String description; // Will be initialized later
void initializeDescription() {
description = 'Initialized';
}
Null Safety Best Practices
// Check before use
String? input;
if (input != null) {
print(input.length); // Safe access
}
// Use null-aware operators
print(input?.length ?? 0);
// Provide defaults
String getMessage(String? input) {
return input ?? 'Default message';
}
// Use late for deferred initialization
class MyClass {
late String _property;
void initialize() {
_property = 'Initialized';
}
String get property => _property;
}
Common Patterns & Idioms
Factory Pattern
class Logger {
static final Logger _instance = Logger._internal();
factory Logger() {
return _instance;
}
Logger._internal();
void log(String message) {
print('[LOG] $message');
}
}
// Usage
var logger1 = Logger();
var logger2 = Logger();
print(identical(logger1, logger2)); // true (same instance)
Builder Pattern
class HttpRequest {
String? url;
String method = 'GET';
Map<String, String> headers = {};
HttpRequest setUrl(String url) {
this.url = url;
return this;
}
HttpRequest setMethod(String method) {
this.method = method;
return this;
}
HttpRequest addHeader(String key, String value) {
headers[key] = value;
return this;
}
void send() {
print('$method $url');
print('Headers: $headers');
}
}
// Usage
HttpRequest()
.setUrl('https://api.example.com')
.setMethod('POST')
.addHeader('Content-Type', 'application/json')
.send();
Type System Comparison
| Feature | Dart | Java | JavaScript | TypeScript |
|---|---|---|---|---|
| Type Safety | Strong, Null-safe | Strong | Weak | Strong (compile-time) |
| Type Inference | Yes | Limited | No | Yes |
| Null Safety | Built-in | Optional | No | Optional |
| Generics | Yes | Yes | No | Yes |
| Dynamic Typing | Optional | No | Yes | Optional |
| Runtime Type Checking | Yes | Yes | Yes | Limited |
Common Challenges & Solutions
Challenge 1: Null Safety Migration
Problem: Converting existing code to null-safe Dart Solution:
// Before (nullable by default)
String name;
// After (explicit nullability)
String? name; // Nullable
late String name; // Late initialization
String name = 'default'; // Non-null with default
Challenge 2: Type Conversion
Problem: Converting between different types safely Solution:
// Safe parsing with error handling
int? parseInteger(String input) {
try {
return int.parse(input);
} catch (e) {
return null;
}
}
// Usage
String userInput = '123';
int? number = parseInteger(userInput);
if (number != null) {
print('Valid number: $number');
}
Challenge 3: Collection Type Safety
Problem: Ensuring type safety in collections Solution:
// Generic collections
List<int> numbers = <int>[1, 2, 3];
Map<String, Person> people = <String, Person>{};
// Type-safe operations
numbers.add(4); // OK
// numbers.add('text'); // Compile error
// Safe casting
dynamic mixed = [1, 2, 3];
if (mixed is List<int>) {
List<int> typedList = mixed;
}
Challenge 4: Async Type Handling
Problem: Working with Future types Solution:
// Future with proper typing
Future<String> fetchData() async {
// Simulate API call
await Future.delayed(Duration(seconds: 1));
return 'Data fetched';
}
// Proper error handling
Future<String?> safeDataFetch() async {
try {
return await fetchData();
} catch (e) {
print('Error: $e');
return null;
}
}
Best Practices & Tips
Code Organization
- Use meaningful variable and function names
- Follow Dart naming conventions (camelCase for variables, PascalCase for classes)
- Group related functionality into classes and libraries
- Use const constructors for immutable objects
- Prefer final over var when values don’t change
Performance Tips
- Use const constructors for compile-time constants
- Prefer int over double when possible
- Use StringBuffer for multiple string concatenations
- Initialize collections with known size when possible
- Use ?? and ??= for null coalescing instead of explicit null checks
Type Safety Guidelines
- Enable null safety in pubspec.yaml
- Use explicit types for public APIs
- Prefer non-nullable types when possible
- Use late sparingly and only when necessary
- Validate input parameters in public methods
Memory Management
- Avoid creating unnecessary objects in loops
- Use object pooling for frequently created objects
- Clean up resources in dispose methods
- Be careful with closures capturing large objects
Development Tools & Environment
Essential Tools
- Dart SDK: Core development kit
- DartPad: Online Dart editor and runner
- VS Code: With Dart extension for development
- IntelliJ IDEA: With Dart plugin
- Dart DevTools: Debugging and performance analysis
Command Line Tools
# Check Dart version
dart --version
# Create new project
dart create my_project
# Run Dart file
dart run lib/main.dart
# Format code
dart format .
# Analyze code
dart analyze
# Run tests
dart test
Package Management
# pubspec.yaml
name: my_project
version: 1.0.0
environment:
sdk: '>=2.17.0 <4.0.0'
dependencies:
http: ^0.13.5
dev_dependencies:
test: ^1.21.0
Quick Reference
Type Declaration Patterns
// Variables
var name = 'Auto-inferred';
String name = 'Explicit type';
final name = 'Runtime constant';
const name = 'Compile-time constant';
late String name; // Late initialization
// Nullable types
String? nullable;
String nonNull = 'value';
// Collections
List<int> numbers = [1, 2, 3];
Set<String> unique = {'a', 'b', 'c'};
Map<String, int> mapping = {'key': 42};
Essential Syntax Patterns
// Null safety
value?.method() // Safe call
value ?? 'default' // Null coalescing
value! // Null assertion
// String interpolation
'Hello $name' // Variable
'Result: ${2 + 3}' // Expression
// Arrow functions
int add(int a, int b) => a + b;
// Cascade operator
object
..method1()
..method2()
..property = value;
This comprehensive cheatsheet covers all fundamental aspects of Dart syntax and types, providing practical examples and best practices for both beginners and intermediate developers working with Dart and Flutter applications.
