Introduction
Dart is a modern, object-oriented programming language developed by Google, primarily used for building mobile, web, server, and desktop applications. It’s the foundation of Flutter framework and offers features like strong typing, null safety, asynchronous programming, and hot reload capabilities. Dart combines the best of both compiled and interpreted languages, making it fast, productive, and scalable for modern application development.
Core Concepts & Principles
Language Fundamentals
- Strongly Typed: Static type checking with type inference
- Object-Oriented: Everything is an object, including numbers and functions
- Null Safety: Built-in protection against null reference errors
- Garbage Collected: Automatic memory management
- Single Inheritance: Classes extend one superclass but can implement multiple interfaces
Key Principles
- Sound Type System: Compile-time and runtime type safety
- Asynchronous Programming: Built-in support for Future, Stream, and async/await
- Mixins: Code reuse mechanism beyond single inheritance
- Generics: Type-safe collections and classes
Data Types & Variables
Basic Data Types
| Type | Description | Example |
|---|---|---|
int | 64-bit integers | int age = 25; |
double | 64-bit floating-point | double price = 19.99; |
String | UTF-16 code sequences | String name = 'John'; |
bool | Boolean values | bool isActive = true; |
var | Type inference | var count = 10; |
dynamic | Dynamic typing | dynamic data = 'text'; |
Variable Declaration
// Explicit typing
int count = 0;
String message = 'Hello';
// Type inference
var name = 'Dart';
var isValid = true;
// Constants
const PI = 3.14159;
final timestamp = DateTime.now();
// Nullable variables (Null Safety)
String? nullableString;
int? nullableInt;
Collections
// Lists
List<String> fruits = ['apple', 'banana', 'orange'];
var numbers = <int>[1, 2, 3, 4, 5];
// Sets
Set<String> uniqueNames = {'Alice', 'Bob', 'Charlie'};
var uniqueNumbers = <int>{1, 2, 3};
// Maps
Map<String, int> ages = {'Alice': 25, 'Bob': 30};
var scores = <String, double>{'math': 95.5, 'science': 88.0};
Control Flow Structures
Conditional Statements
// If-else
if (age >= 18) {
print('Adult');
} else if (age >= 13) {
print('Teenager');
} else {
print('Child');
}
// Ternary operator
String status = age >= 18 ? 'Adult' : 'Minor';
// Switch statement
switch (grade) {
case 'A':
print('Excellent');
break;
case 'B':
print('Good');
break;
default:
print('Keep trying');
}
Loops
// For loop
for (int i = 0; i < 5; i++) {
print(i);
}
// For-in loop
for (String fruit in fruits) {
print(fruit);
}
// While loop
while (count < 10) {
count++;
}
// Do-while loop
do {
print(count);
count--;
} while (count > 0);
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
double multiply(double x, double y) => x * y;
// Optional parameters
void displayInfo(String name, [int? age]) {
print('Name: $name, Age: ${age ?? 'Unknown'}');
}
// Named parameters
void createUser({required String name, int age = 0}) {
print('User: $name, Age: $age');
}
Higher-Order Functions
// Function as parameter
void executeFunction(Function callback) {
callback();
}
// Anonymous functions
var numbers = [1, 2, 3, 4, 5];
var doubled = numbers.map((n) => n * 2).toList();
// Function composition
Function compose(Function f, Function g) {
return (x) => f(g(x));
}
Object-Oriented Programming
Classes & Objects
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 description => '$name ($age years old)';
// Setter
set updateAge(int newAge) {
if (newAge >= 0) age = newAge;
}
}
// Usage
var person = Person('Alice', 25);
person.introduce();
Inheritance
class Animal {
String name;
Animal(this.name);
void makeSound() {
print('Some generic animal sound');
}
}
class Dog extends Animal {
String breed;
Dog(String name, this.breed) : super(name);
@override
void makeSound() {
print('$name barks: Woof!');
}
}
Mixins
mixin Flyable {
void fly() {
print('Flying high!');
}
}
mixin Swimmable {
void swim() {
print('Swimming gracefully!');
}
}
class Duck extends Animal with Flyable, Swimmable {
Duck(String name) : super(name);
}
Abstract Classes & Interfaces
abstract class Shape {
double area();
void display();
}
class Circle implements Shape {
double radius;
Circle(this.radius);
@override
double area() => 3.14159 * radius * radius;
@override
void display() => print('Circle with radius $radius');
}
Asynchronous Programming
Future & Async/Await
// Future function
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 2));
return 'Data loaded';
}
// Using async/await
void loadData() async {
try {
String data = await fetchData();
print(data);
} catch (e) {
print('Error: $e');
}
}
// Future methods
Future<String> processData() {
return fetchData()
.then((data) => data.toUpperCase())
.catchError((error) => 'Error occurred');
}
Streams
// Stream creation
Stream<int> numberStream() async* {
for (int i = 1; i <= 5; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
// Stream usage
void listenToStream() {
numberStream().listen(
(number) => print('Received: $number'),
onError: (error) => print('Error: $error'),
onDone: () => print('Stream completed'),
);
}
Error Handling
Exception Handling
// Try-catch-finally
void handleErrors() {
try {
int result = 10 ~/ 0;
print(result);
} catch (e) {
print('Error occurred: $e');
} finally {
print('Cleanup code');
}
}
// Specific exception types
void parseNumber(String input) {
try {
int number = int.parse(input);
print('Number: $number');
} on FormatException {
print('Invalid number format');
} catch (e) {
print('Unknown error: $e');
}
}
// Custom exceptions
class CustomException implements Exception {
final String message;
CustomException(this.message);
@override
String toString() => 'CustomException: $message';
}
Null Safety Features
Null Safety Operators
| Operator | Description | Example |
|---|---|---|
? | Nullable type | String? name; |
! | Null assertion | name!.length |
?? | Null coalescing | name ?? 'Default' |
??= | Null assignment | name ??= 'Default' |
?. | Null-aware access | person?.name |
Null Safety Best Practices
// Safe null checking
String? getUserName() {
return null; // Might return null
}
void displayUserName() {
String? name = getUserName();
// Safe approach
if (name != null) {
print('Name length: ${name.length}');
}
// Null-aware operator
print('Name: ${name ?? 'Anonymous'}');
// Null-aware method call
print('Uppercase: ${name?.toUpperCase() ?? 'N/A'}');
}
Common Collections & Operations
List Operations
var numbers = [1, 2, 3, 4, 5];
// Basic operations
numbers.add(6);
numbers.addAll([7, 8, 9]);
numbers.remove(3);
numbers.removeAt(0);
// Functional operations
var doubled = numbers.map((n) => n * 2).toList();
var evens = numbers.where((n) => n % 2 == 0).toList();
var sum = numbers.reduce((a, b) => a + b);
var found = numbers.firstWhere((n) => n > 5, orElse: () => -1);
Map Operations
var userScores = <String, int>{'Alice': 95, 'Bob': 87};
// Basic operations
userScores['Charlie'] = 92;
userScores.putIfAbsent('David', () => 88);
userScores.remove('Bob');
// Iteration
userScores.forEach((name, score) {
print('$name: $score');
});
// Transformation
var highScorers = userScores.entries
.where((entry) => entry.value > 90)
.map((entry) => entry.key)
.toList();
Best Practices & Tips
Code Organization
- Use meaningful names: Choose descriptive variable and function names
- Follow naming conventions: camelCase for variables, PascalCase for classes
- Keep functions small: Single responsibility principle
- Use const constructors: For immutable objects
- Prefer final over var: When values won’t change
Performance Tips
// Prefer const constructors
const CircularProgressIndicator();
// Use string interpolation
String message = 'Hello, $name!'; // Good
String message = 'Hello, ' + name + '!'; // Avoid
// Cache expensive operations
late final String expensiveValue = computeExpensiveValue();
// Use appropriate collection types
Set<String> uniqueItems = {}; // For unique values
List<String> orderedItems = []; // For ordered collections
Null Safety Best Practices
// Initialize non-nullable variables
class User {
String name;
int age;
User(this.name, this.age); // Required parameters
}
// Use late for delayed initialization
class DatabaseConnection {
late Database _db;
Future<void> initialize() async {
_db = await Database.open('path');
}
}
Common Challenges & Solutions
Challenge 1: Null Reference Errors
Solution: Enable null safety and use nullable types appropriately
String? getValue() => null;
void processValue() {
String? value = getValue();
print(value?.length ?? 0); // Safe access
}
Challenge 2: Asynchronous Programming Complexity
Solution: Use async/await pattern consistently
Future<void> loadUserData() async {
try {
final user = await fetchUser();
final profile = await fetchProfile(user.id);
updateUI(user, profile);
} catch (e) {
showError(e.toString());
}
}
Challenge 3: State Management
Solution: Use proper state management patterns
class Counter {
int _value = 0;
int get value => _value;
void increment() {
_value++;
notifyListeners(); // If using ChangeNotifier
}
}
Development Tools & Resources
Essential Tools
| Tool | Purpose | Usage |
|---|---|---|
dart analyze | Static analysis | dart analyze lib/ |
dart format | Code formatting | dart format lib/ |
dart test | Run tests | dart test |
dart pub get | Install dependencies | dart pub get |
dart doc | Generate documentation | dart doc |
Debugging Tips
// Debug prints
print('Debug: $variableName');
// Assertions
assert(age >= 0, 'Age cannot be negative');
// Debugger statement
debugger(); // Breaks in IDE debugger
Further Learning Resources
- Official Documentation: dart.dev
- Language Tour: dart.dev/guides/language/language-tour
- Effective Dart: dart.dev/guides/language/effective-dart
- DartPad: dartpad.dev – Online Dart editor
- Package Repository: pub.dev – Dart and Flutter packages
- Flutter Documentation: flutter.dev – For mobile app development
- Dart SDK: Download and installation guides
- Community: Stack Overflow, Reddit r/dartlang, Discord communities
Quick Reference Commands
# Create new project
dart create my_project
# Run Dart file
dart run main.dart
# Install dependencies
dart pub get
# Run tests
dart test
# Analyze code
dart analyze
# Format code
dart format .
This cheatsheet covers the essential aspects of Dart programming language, from basic syntax to advanced features like null safety and asynchronous programming. Use it as a quick reference while developing Dart applications or learning the language.
