dart-cheat-sheet
MAIN FUNCTION
void main() { print('Hello, World!'); }
VARIABLES
// Variables can be declared using the var or type name syntax var age = 25; // inferred int created with var int count = 0; // explicit int declaration double pi = 3.14; // double num value = 42; // generic numeric type String name = 'Alice'; // single quotes String message = "Hello, $name!"; // double quotes with string interpolation bool isRaining = true; // booleans are declared using the bool keyword dynamic dynamicVar = 'hello'; // dynamic type can hold any value and its type determined at runtime final companyName = 'Acme Inc.'; // final keyword creates a variable that can be set only once const PI = 3.14159; // const keyword creates a compile-time constant
OPERATORS
// Arithmetic operators var sum = 10 + 20; // addition var difference = 40 - 30; // subtraction var product = 2 * 5; // multiplication var quotient = 15 / 3; // division var remainder = 20 % 3; // modulus // Comparison operators var isEqual = (5 == 5); // equality var notEqual = (5 != 6); // inequality var greaterThan = (5 > 3); // greater than var lessThan = (5 < 7); // less than var greaterOrEqual = (5 >= 5); // greater than or equal to var lessOrEqual = (5 <= 5); // less than or equal to // Logical operators var and = true && false; // logical and var or = true || false; // logical or var not = !true; // logical not // Assignment operators var x = 10; // simple assignment x += 5; // addition assignment (same as x = x + 5) x -= 2; // subtraction assignment (same as x = x - 2) x *= 3; // multiplication assignment (same as x = x * 3) x /= 2; // division assignment (same as x = x / 2) x %= 4; // modulus assignment (same as x = x % 4) // Conditional operator var isEven = (x % 2 == 0) ? true : false; // if-else shorthand
COMMENTS
// Single-line comments start with // // This is a single-line comment // Multi-line comments start with /* and end with */ /* This is a multi-line comment It can span multiple lines */ // Documentation comments are used to generate documentation for libraries, classes, functions, and variables /// This is a documentation comment for a class. /// It should describe what the class does and its properties and methods. class MyClass { int myProperty; /// This is a documentation comment for a method. /// It should describe what the method does and its parameters. void myMethod(int param) { // method code here } }
METADATA
// Metadata provides additional information about the code to tools and other programs // Metadata provides additional information about the code to tools and other programs // Metadata can be added to classes, methods, variables, and parameters using the @ symbol // Common metadata includes: // - @deprecated: indicates that a method or variable is no longer recommended for use // - @override: indicates that a method is intended to override a method from a superclass or interface // - @immutable: indicates that a class or property is read-only // - @proxy: indicates that a class should be treated as a dynamic proxy @deprecated void myDeprecatedFunction() { // deprecated function code here } class MyClass { @override void myMethod() { // method code here } } @immutable class MyImmutableClass { final int myProperty; const MyImmutableClass(this.myProperty); } @proxy class MyDynamicClass { // proxy code here }
LIBRARIES & IMPORTS
// Dart code is organized into libraries, which are collections of related code // Libraries are defined using the 'library' keyword, followed by the name of the library library my_library; // Code from other libraries can be accessed using the 'import' keyword import 'dart:math'; // import a core Dart library import 'package:flutter/material.dart'; // import a package from pub.dev // The 'as' keyword can be used to give an imported library a different name import 'package:flutter/cupertino.dart' as cupertino; // The 'show' and 'hide' keywords can be used to selectively import or hide parts of a library import 'package:my_package/my_module.dart' show myFunction; import 'package:my_package/my_module.dart' hide myPrivateFunction; // Code can also be exported from a library using the 'export' keyword export 'my_other_library.dart'; // Libraries can have a part directive to include source code from other files part 'my_file.dart';
TYPES
- built-in types
// Dart has built-in types for numbers, strings, and booleans // Numbers can be declared as integers or doubles int age = 42; // integer double pi = 3.14; // double // Strings can be declared using single or double quotes String name = 'Alice'; // single quotes String message = "Hello, $name!"; // double quotes with string interpolation // Booleans are declared using the 'bool' keyword bool isRaining = true; // Methods for numbers: age.toString(); // convert to string pi.round(); // round to nearest integer pi.floor(); // round down to integer pi.ceil(); // round up to integer // Methods for strings: name.length; // get length name.toUpperCase(); // convert to uppercase message.contains('Alice'); // check if contains substring message.replaceAll('Alice', 'Bob'); // replace substring // Methods for booleans: isRaining.toString(); // convert to string !isRaining; // logical NOT isRaining && isCold; // logical AND isRaining || isSunny; // logical OR
- collections
// Dart has built-in types for lists, sets, and maps // Lists can be declared using square brackets List<int> numbers = [1, 2, 3, 4, 5]; // Sets can be declared using curly braces Set<String> fruits = {'apple', 'banana', 'cherry'}; // Maps can be declared using curly braces with key-value pairs Map<String, int> ages = {'Alice': 42, 'Bob': 37}; // Methods for lists: numbers.length; // get length numbers[2]; // access element at index numbers.indexOf(3); // find index of element numbers.add(6); // add element to end numbers.remove(4); // remove element numbers.forEach((number) => print(number)); // iterate over elements // Methods for sets: fruits.length; // get length fruits.contains('banana'); // check if contains element fruits.add('date'); // add element fruits.remove('apple'); // remove element fruits.forEach((fruit) => print(fruit)); // iterate over elements // Methods for maps: ages.length; // get length ages['Alice']; // access value with key ages.containsKey('Charlie'); // check if contains key ages.putIfAbsent('Charlie', () => 30); // add key-value pair if absent ages.remove('Bob'); // remove key-value pair ages.forEach((key, value) => print('$key is $value years old')); // iterate over key-value pairs
- operators
// Dart has operators and control flow statements for working with collections // Spread operator var numbers = [1, 2, 3]; var moreNumbers = [0, ...numbers]; // spread operator inserts contents of numbers into moreNumbers // For loops for (var i = 0; i < numbers.length; i++) { print(numbers[i]); // prints each element in numbers } // For-in loops for (var number in numbers) { print(number); // prints each element in numbers } // forEach method numbers.forEach((number) => print(number)); // prints each element in numbers using a lambda function // Map method var doubledNumbers = numbers.map((number) => number * 2); // creates a new list with each element in numbers multiplied by 2 // Where method var evenNumbers = numbers.where((number) => number % 2 == 0); // creates a new list with only the even elements in numbers // Reduce method var sum = numbers.reduce((value, element) => value + element); // computes the sum of all elements in numbers // Conditional expressions var age = 21; var isLegal = age >= 18 ? 'Legal' : 'Illegal'; // ternary operator - sets isLegal to 'Legal' if age is greater than or equal to 18, and 'Illegal' otherwise
- generics
// Dart supports generics for creating reusable code // Generic classes class Box<T> { T item; Box(this.item); T getItem() => item; } // Generic methods T getFirst<T>(List<T> items) => items[0]; // Usage examples var intBox = Box<int>(10); // creates a Box that can hold integers var stringBox = Box<String>('hello'); // creates a Box that can hold strings var numbers = [1, 2, 3]; var firstNumber = getFirst(numbers); // gets the first number in the list
- typedef
// Dart supports typedefs for defining function types // Defining a typedef for a function type typedef bool Filter(int number); // Example of a function that takes a function type as a parameter List<int> filterList(List<int> list, Filter filter) { return list.where((number) => filter(number)).toList(); } // Usage examples bool isEven(int number) => number % 2 == 0; bool isOdd(int number) => number % 2 == 1; var numbers = [1, 2, 3, 4, 5]; var evenNumbers = filterList(numbers, isEven); // filters even numbers from the list var oddNumbers = filterList(numbers, isOdd); // filters odd numbers from the list
CONTROL FLOW
- if-else Statements
// The if-else statement is used to execute code based on a condition if (condition) { // code to execute if the condition is true } else { // code to execute if the condition is false }
- for loops
// The for loop is used to execute code repeatedly for a specific number of times for (var i = 0; i < 10; i++) { // code to execute on each iteration }
- while loops
// The while loop is used to execute code repeatedly while a condition is true while (condition) { // code to execute while the condition is true }
- do-while loops
// The do-while loop is used to execute code repeatedly at least once, and then as long as a condition is true do { // code to execute at least once } while (condition);
- switch statements
// The switch statement is used to execute different code blocks based on different conditions switch (variable) { case value1: // code to execute if variable equals value1 break; case value2: // code to execute if variable equals value2 break; default: // code to execute if variable does not equal any of the cases break; }
ERROR HANDLING
// Dart provides several ways to handle errors and exceptions // Using try-catch blocks to handle exceptions try { var result = 42 ~/ 0; // throws an IntegerDivisionByZeroException } catch (e) { print("An exception occurred: $e"); // prints "An exception occurred: IntegerDivisionByZeroException" } // Using on clauses to handle specific exceptions try { var result = 42 ~/ 0; // throws an IntegerDivisionByZeroException } on IntegerDivisionByZeroException { print("Cannot divide by zero"); } // Using finally clauses to execute code after try-catch blocks try { var result = 42 ~/ 0; // throws an IntegerDivisionByZeroException } catch (e) { print("An exception occurred: $e"); } finally { print("This code always runs"); } // Using rethrow to propagate an exception to the calling function void riskyFunction() { try { var result = 42 ~/ 0; // throws an IntegerDivisionByZeroException } catch (e) { // rethrows the exception to the calling function rethrow; } } // Using assert statements to check for errors during development void printNumber(int number) { assert(number >= 0, "The number must be greater than or equal to zero"); print(number); }
CLASSES & OBJECTS
// Dart is an object-oriented language, and classes are a fundamental building block // Defining a class class Person { String name; int age; // A constructor with named parameters Person({required this.name, required this.age}); // A named constructor Person.fromJson(Map<String, dynamic> json) { name = json['name']; age = json['age']; } // A method that returns a string String greet() { return "Hello, my name is $name and I am $age years old"; } } // Inheriting from a class class Employee extends Person { String department; // A constructor that calls the super constructor Employee({required String name, required int age, required this.department}) : super(name: name, age: age); // Overriding a method from the parent class @override String greet() { return "Hello, my name is $name, I am $age years old, and I work in $department"; } } // Creating objects from classes var person = Person(name: "Alice", age: 25); var employee = Employee(name: "Bob", age: 30, department: "Sales"); // Calling methods on objects print(person.greet()); // prints "Hello, my name is Alice and I am 25 years old" print(employee.greet()); // prints "Hello, my name is Bob, I am 30 years old, and I work in Sales"
EXTENSION
// Define a class to be extended class Person { String name; int age; Person({required this.name, required this.age}); String greet() { return "Hello, my name is $name and I am $age years old"; } } // Define an extension to add a new method to Person extension on Person { String introduce(String city) { return "Hi, my name is $name and I am from $city"; } } void main() { var person = Person(name: "Alice", age: 25); print(person.introduce("New York")); // prints "Hi, my name is Alice and I am from New York" }
ENUM
// An enum is a special kind of class used to represent a fixed number of values enum Flavor { vanilla, chocolate, strawberry, mint, } // Enums can have properties and methods just like classes extension FlavorExtensions on Flavor { String get name { return this.toString().split('.').last; } bool get isSweet { switch (this) { case Flavor.vanilla: case Flavor.chocolate: return true; case Flavor.strawberry: case Flavor.mint: return false; } } } // Enums can be used like any other type in Dart void printFlavorInfo(Flavor flavor) { print("The flavor is ${flavor.name}"); print("Is it sweet? ${flavor.isSweet}"); } // Example usage void main() { var myFlavor = Flavor.chocolate; printFlavorInfo(myFlavor); }
MIXIN
// A mixin is a way to reuse a class's code in multiple class hierarchies // Defining a mixin mixin Dancer { void dance() { print("Dancing..."); } } // Defining a class that uses the mixin class Person with Dancer { String name; int age; // A constructor with named parameters Person({required this.name, required this.age}); // A method that returns a string String greet() { return "Hello, my name is $name and I am $age years old"; } } // Creating an object from the class var person = Person(name: "Alice", age: 25); // Calling a method on the object that was defined in the mixin person.dance(); // prints "Dancing..."
CALLABLE CLASSES
// A callable class is one that can be invoked as a function class Greeting { String message; // The constructor sets the message property Greeting(this.message); // The call() method allows instances of this class to be called as functions String call(String name) { return "$message, $name!"; } } // Example usage void main() { var hello = Greeting("Hello"); var goodbye = Greeting("Goodbye"); // Invoke the objects as functions print(hello("Alice")); // prints "Hello, Alice!" print(goodbye("Bob")); // prints "Goodbye, Bob!" }
NULL SAFETY
void main() { // Declaring nullable variables with the "?" operator String? name; int? age; // Attempting to assign null to non-nullable variables causes an error // String name; // int age; // Using the "!" operator to assert that a nullable variable is not null name = "Alice"; age = 25; print("Hello, my name is ${name!} and I am ${age!} years old"); // Using the "?? " operator to provide a default value for a nullable variable String? jobTitle; String message = "Hello"; message += jobTitle ?? "there"; print(message); // Using the "late" keyword to indicate that a non-nullable variable will be assigned later late String favoriteColor; favoriteColor = "blue"; print("My favorite color is $favoriteColor"); // Using the "required" keyword in constructors to indicate non-nullability final person = Person(name: "Bob", age: 30); print("Hello, my name is ${person.name} and I am ${person.age} years old"); } class Person { final String name; final int age; Person({required this.name, required this.age}); }
ASYNCHRONOUS PROGRAMMING
- future : object that represents a value that may not be available yet.
void main() { // Creating a Future object that resolves to a value after a delay Future<String> delayedHello(int seconds) { return Future.delayed(Duration(seconds: seconds), () => "Hello"); } // Using a Future to execute code asynchronously print("Before the Future"); delayedHello(2).then((value) => print(value)); print("After the Future"); } // prints : // Before the future // After the future // Hello, world!
- async & await : makes working with
future
more convenient.
void main() async { // Using the "async" keyword to mark a function as asynchronous Future<String> delayedHello(int seconds) { return Future.delayed(Duration(seconds: seconds), () => "Hello"); } // Using "await" to wait for a Future to complete before continuing execution print("Before the Future"); String value = await delayedHello(2); print(value); print("After the Future"); } // prints : // Before the future // After the future // Hello, world!
- the
async
keyword is used to mark themain
function as an asynchronous function, and theawait
keyword is used to pause the execution of the function until thedelayedHello()
Future has completed. - This allows the code to be written in a more synchronous style, where each line of code is executed one after the other, without blocking the event loop.