Dart language
- Dart language reference
Hello World
Section titled “Hello World”The most basic Dart program that prints “Hello, World!” to the console. Every Dart application must have a main() function as its entry point.
void main() { print('Hello, World!');}Variables & Data Types
Section titled “Variables & Data Types”Variable Declaration
Section titled “Variable Declaration”Different ways to declare variables in Dart with various mutability and type constraints.
var name = 'John'; // Type inferred as StringString name = 'John'; // Explicit type declarationfinal age = 30; // Runtime constant (can't be reassigned)const pi = 3.14; // Compile-time constantdynamic dynamicVar = 'hello'; // Can hold any type, bypasses static type checkingBasic Data Types
Section titled “Basic Data Types”Dart’s built-in primitive and core data types.
// Numbers - for integer and floating-point valuesint age = 25; // Integer valuesdouble price = 99.99; // Floating-point valuesnum anyNumber = 10; // Can be either int or double
// Strings - for text dataString name = 'Alice'; // Single line stringString multiLine = '''This is amulti-line string'''; // Multi-line string using triple quotes
// Booleans - for true/false valuesbool isActive = true;
// Runes - for representing Unicode code pointsvar heart = '\u2665'; // Heart symbol
// Symbols - used for reflection and metadata#symbolName; // Symbol literalOperators
Section titled “Operators”Arithmetic Operators
Section titled “Arithmetic Operators”Mathematical operations for performing calculations.
var a = 10, b = 3;print(a + b); // 13 - Additionprint(a - b); // 7 - Subtractionprint(a * b); // 30 - Multiplicationprint(a / b); // 3.333... - Division (returns double)print(a ~/ b); // 3 - Integer division (truncates to integer)print(a % b); // 1 - Modulus (remainder)Equality & Relational Operators
Section titled “Equality & Relational Operators”Operators for comparing values and determining relationships.
print(a == b); // false - Equalityprint(a != b); // true - Inequalityprint(a > b); // true - Greater thanprint(a < b); // false - Less thanprint(a >= b); // true - Greater than or equal toprint(a <= b); // false - Less than or equal toLogical Operators
Section titled “Logical Operators”Boolean logic operations for combining conditions.
bool x = true, y = false;print(x && y); // false - Logical AND (both must be true)print(x || y); // true - Logical OR (at least one true)print(!x); // false - Logical NOT (inverts the value)Type Test Operators
Section titled “Type Test Operators”Operators for checking types at runtime.
var value = 'hello';print(value is String); // true - Type checkprint(value is! int); // true - Negated type checkCascade Operator (..)
Section titled “Cascade Operator (..)”Allows multiple operations on the same object without repeating the object reference.
var person = Person() ..name = 'John' // Sets name property ..age = 30 // Sets age property ..introduce(); // Calls introduce methodNull-aware Operators
Section titled “Null-aware Operators”Special operators for handling null values safely.
String? nullableString;print(nullableString ?? 'default'); // 'default' - Null coalescing (returns right if left is null)print(nullableString?.length); // null - Null-aware access (returns null if object is null)nullableString ??= 'new value'; // Null-aware assignment (assigns only if currently null)Control Flow
Section titled “Control Flow”If-Else
Section titled “If-Else”Conditional execution based on boolean expressions.
if (age < 18) { print('Minor');} else if (age < 65) { print('Adult');} else { print('Senior');}Switch Statement
Section titled “Switch Statement”Multi-way branch based on a single value, more efficient than multiple if-else statements.
switch (grade) { case 'A': print('Excellent'); break; // Required to prevent fall-through case 'B': print('Good'); break; default: // Handles all other cases print('Unknown');}For Loops
Section titled “For Loops”Different ways to iterate over sequences or execute code repeatedly.
// Traditional for loop - when you need index controlfor (var i = 0; i < 5; i++) { print(i);}
// For-in loop - for iterating over iterables (lists, sets, etc.)var list = [1, 2, 3];for (var item in list) { print(item);}
// forEach method - functional style iterationlist.forEach((item) => print(item));While Loops
Section titled “While Loops”Execute code repeatedly while a condition remains true.
// While loop - checks condition before executionvar i = 0;while (i < 5) { print(i); i++;}
// Do-while loop - executes at least once, then checks conditionvar j = 0;do { print(j); j++;} while (j < 5);Functions
Section titled “Functions”Basic Function
Section titled “Basic Function”Reusable blocks of code that perform specific tasks.
int add(int a, int b) { return a + b;}
// Arrow function - shorthand for single expression functionsint multiply(int a, int b) => a * b;Optional Parameters
Section titled “Optional Parameters”Parameters that can be omitted when calling a function.
// Named parameters - specified by name, enclosed in {}void greet({String name = 'Guest', int age = 0}) { print('Hello $name, age $age');}greet(name: 'John', age: 30); // Calling with named parameters
// Positional parameters - optional parameters in []void introduce(String name, [int? age]) { print('I am $name${age != null ? ', $age years old' : ''}');}introduce('Alice', 25); // With optional parameterintroduce('Bob'); // Without optional parameterFirst-class Functions
Section titled “First-class Functions”Functions can be assigned to variables, passed as arguments, and returned from other functions.
void executeFunction(Function func) { func(); // Execute the passed function}
var sayHello = () => print('Hello'); // Function assigned to variableexecuteFunction(sayHello); // Function passed as argumentAnonymous Functions
Section titled “Anonymous Functions”Functions without a name, often used as arguments to other functions.
var numbers = [1, 2, 3];numbers.forEach((number) { // Anonymous function as argument print(number * 2);});Classes & Objects
Section titled “Classes & Objects”Basic Class
Section titled “Basic Class”Blueprint for creating objects with properties and methods.
class Person { // Fields - variables that belong to the class String name; int age;
// Constructor - special method for creating instances Person(this.name, this.age); // Shorthand for assigning parameters to fields
// Named constructor - alternative way to create instances Person.anonymous() : name = 'Anonymous', age = 0;
// Method - function that belongs to the class void introduce() { print('I am $name, $age years old'); }
// Getter - special method that returns a value String get description => '$name ($age)';
// Setter - special method that sets a value set updateAge(int newAge) { age = newAge; }}
// Usage - creating and using class instancesvar person = Person('John', 30);person.introduce();Inheritance
Section titled “Inheritance”Creating a new class based on an existing class, inheriting its properties and methods.
class Employee extends Person { // Employee inherits from Person String position;
Employee(String name, int age, this.position) : super(name, age); // super calls parent constructor
@override // Indicates method is overriding parent method void introduce() { super.introduce(); // Call parent method print('I work as a $position'); }}Abstract Classes
Section titled “Abstract Classes”Classes that can’t be instantiated directly, used as base classes for inheritance.
abstract class Animal { // Cannot create Animal instances directly void makeSound(); // Abstract method (no implementation)
void sleep() { // Concrete method with implementation print('Sleeping...'); }}
class Dog extends Animal { @override void makeSound() { // Must implement abstract method print('Woof!'); }}Interfaces
Section titled “Interfaces”Contracts that classes can implement, requiring them to provide specific methods.
class Logger { // Regular class used as interface void log(String message) => print(message);}
class ConsoleLogger implements Logger { // Implements Logger interface @override void log(String message) { // Must implement all interface methods print('LOG: $message'); }}Null Safety
Section titled “Null Safety”Nullable Types
Section titled “Nullable Types”Dart’s null safety feature prevents null reference errors at compile time.
String? nullableString = null; // ? indicates variable can be nullString nonNullableString = 'hello'; // Cannot be null (compile-time error if assigned null)
// Null assertion operator - tells compiler value won't be null at runtimeString definitelyString = nullableString!; // Use with caution - can cause runtime error if null
// Late initialization - variable will be initialized before use, but not at declarationlate String lateString;void initialize() { lateString = 'initialized'; // Must be initialized before use}Null-aware Operators
Section titled “Null-aware Operators”Operators that handle null values gracefully without causing exceptions.
String? name;print(name?.length); // null - Safe access (returns null instead of throwing error)print(name ?? 'default'); // 'default' - Provides default value if nullname ??= 'assigned'; // Assigns value only if variable is currently nullCollections
Section titled “Collections”Ordered collections of elements (like arrays in other languages).
List<int> numbers = [1, 2, 3]; // Type-annotated listvar names = <String>['John', 'Alice']; // Type-inferred list
// List methods - operations on listsnumbers.add(4); // Add element to endnumbers.removeAt(0); // Remove element at indexprint(numbers.length); // Get number of elementsprint(numbers.contains(2)); // Check if element exists
// List properties - attributes of listsprint(numbers.first); // First elementprint(numbers.last); // Last elementprint(numbers.isEmpty); // Check if empty
// Spread operator - expands collections into other collectionsvar combined = [...numbers, ...names]; // Combine two listsUnordered collections of unique elements.
Set<String> countries = {'USA', 'UK', 'Canada'}; // Type-annotated setvar numbers = <int>{1, 2, 3}; // Type-inferred set
// Set operations - mathematical operations on setsvar set1 = {1, 2, 3};var set2 = {3, 4, 5};print(set1.union(set2)); // {1, 2, 3, 4, 5} - All elements from both setsprint(set1.intersection(set2)); // {3} - Elements common to both setsCollections of key-value pairs (like dictionaries or objects).
Map<String, int> ages = { // Type-annotated map (String keys, int values) 'John': 30, 'Alice': 25,};
var scores = <String, int>{}; // Empty map with type inference
// Map operations - working with key-value pairsages['Bob'] = 28; // Add new key-value pair or update existingprint(ages['John']); // 30 - Access value by keyprint(ages.containsKey('Alice')); // true - Check if key exists
// Iterating - processing each key-value pairages.forEach((key, value) { print('$key: $value');});Exception Handling
Section titled “Exception Handling”Try-Catch
Section titled “Try-Catch”Handling errors and exceptional situations gracefully.
try { var result = 10 ~/ 0; // This will throw an exception} on IntegerDivisionByZeroException { // Catch specific exception type print('Cannot divide by zero');} catch (e) { // Catch any other exception print('Error: $e');} finally { // Always executes, used for cleanup print('This always executes');}Throwing Exceptions
Section titled “Throwing Exceptions”Creating and raising exceptions in your code.
void checkAge(int age) { if (age < 0) { throw ArgumentError('Age cannot be negative'); // Throw built-in exception }}
// Custom exception - user-defined exception typesclass CustomException implements Exception { final String message; CustomException(this.message);
@override String toString() => 'CustomException: $message'; // Custom string representation}Asynchronous Programming
Section titled “Asynchronous Programming”Futures
Section titled “Futures”Representing a potential value or error that will be available at some time in the future.
Future<String> fetchUser() async { // async marks function as asynchronous await Future.delayed(Duration(seconds: 2)); // Simulate network delay return 'User data'; // Return value wrapped in Future}
void main() async { // main can also be async print('Loading...'); var user = await fetchUser(); // await pauses execution until Future completes print(user);
// Error handling with async/await try { var data = await fetchUser(); } catch (e) { print('Error: $e'); }}Streams
Section titled “Streams”Sequences of asynchronous events that can be listened to multiple times.
Stream<int> countStream(int max) async* { // async* for generator functions for (int i = 1; i <= max; i++) { await Future.delayed(Duration(seconds: 1)); // Wait between events yield i; // Emit value to stream }}
void main() async { await for (var number in countStream(5)) { // await for processes stream events print(number); }}Generics
Section titled “Generics”Generic Classes
Section titled “Generic Classes”Classes that can work with any data type while maintaining type safety.
class Box<T> { // T is type parameter T value;
Box(this.value);
T getValue() => value;}
var stringBox = Box<String>('hello'); // Box specialized for Stringvar intBox = Box<int>(42); // Box specialized for intGeneric Methods
Section titled “Generic Methods”Methods that can work with different types while maintaining type safety.
T first<T>(List<T> items) { // Generic method with type parameter T return items[0];}
var firstString = first<String>(['a', 'b', 'c']); // T is Stringvar firstInt = first<int>([1, 2, 3]); // T is intMixins
Section titled “Mixins”A way to reuse code across multiple class hierarchies without using inheritance.
mixin Logger { // mixin keyword defines a mixin void log(String message) { print('LOG: $message'); }}
mixin Timestamp { String get timestamp => DateTime.now().toString();}
class Application with Logger, Timestamp { // with keyword includes mixins void run() { log('Application started at $timestamp'); // Use mixin functionality }}Extensions
Section titled “Extensions”Adding functionality to existing libraries or classes without modifying their source code.
extension StringExtensions on String { // Extension on String type String get reversed => split('').reversed.join(); // New getter property
bool get isPalindrome { var clean = replaceAll(RegExp(r'[^a-zA-Z0-9]'), '').toLowerCase(); return clean == clean.reversed; }}
void main() { print('hello'.reversed); // 'olleh' - Using extension method print('racecar'.isPalindrome); // true - Using extension property}Libraries & Imports
Section titled “Libraries & Imports”Importing
Section titled “Importing”Including code from other files or packages in your Dart program.
// Import entire libraryimport 'dart:math'; // Dart core library
// Import with prefix - avoid name conflictsimport 'package:my_package/my_library.dart' as mylib;
// Import only specific members - reduce namespace pollutionimport 'package:my_package/my_library.dart' show SomeClass;
// Import except specific members - exclude certain membersimport 'package:my_package/my_library.dart' hide SomeClass;
// Deferred loading - load library only when needed (lazy loading)import 'package:heavy_library/heavy.dart' deferred as heavy;Exporting
Section titled “Exporting”Making library members available to other libraries that import it.
// my_library.dartlibrary my_library; // Library directive (optional but recommended)
export 'src/utils.dart'; // Re-export all public membersexport 'src/models.dart'; // Re-export from another filePart/Part of
Section titled “Part/Part of”Splitting a library across multiple files while maintaining a single library namespace.
// main.dartlibrary my_library; // Main library file
part 'utils.dart'; // Include part filespart 'models.dart';
// utils.dartpart of my_library; // Declare as part of main library
// models.dartpart of my_library; // All parts share the same namespace