Dart Cheatsheet
Dart Cheatsheet
Basics
Variables
String name = "John"; // Explicit type
int age = 25;
double height = 5.9;
bool isStudent = true;
**When you use var, Dart will automatically infer the type of the variable based on the value
assigned to it.
Once a type is inferred, the variable’s type is fixed for that instance (it can't change). Dart knows
the variable’s type at compile-time, which means you catch type errors early.
When you use dynamic, the variable’s type is not checked at compile-time, meaning you can
assign any value to it, and its type can change at runtime.With dynamic, the compiler can't
catch errors where you try to use a value in a way that doesn't match its type. You only find out
at runtime, which can lead to bugs that are harder to debug, so avoid it as much as you can.
Null Safety
Nullable Types
Null Assertion
String? name = "John";
print(name!); // Assumes not null
Null-Aware Operators
print(name ?? "Default"); // If null, use "Default"
name?.toUpperCase(); // If not null, call method
name.toUpperCase(); //will give error if name is null
name?.toUpperCase(); //will not give error if null
● In Dart, variables declared outside functions (at the top level) are considered global
variables, and you can change their values. However, if you declare them as const or
final, their values can't be changed, so top-level vars in Dart are mutable unless
marked final or const.
2. Control Flow
If-Else
if (age > 18) {
print("Adult");
} else if (age == 18) {
print("Just an adult!");
} else {
print("Minor");
}
For Loop
for (var i = 0; i < 5; i++) {
print(i);
}
// For-in
var items = ['apple', 'banana'];
for (var item in items) {
print(item);
}
do {
print("Running");
} while (condition);
Switch-Case
switch (age) {
case 18:
print("Just adult!");
break;
case 25:
print("Quarter life!");
break;
default:
print("Age is just a number!");
}
case 1 -> print("Monday"); //arrow notation
Case 1 when age>=18 ->print(“yes”); //allowed
3. Functions
Defining Functions
void greet(String name) {
print("Hello $name!");
}
Optional Parameters
Arrow Functions
int multiply(int a, int b) => a * b;
Named Parameters: Use {} and call with parameter names for readability.
Optional Parameters: Use [] or {} to make parameters optional.
Default Values: Provide defaults for optional parameters.
Syntax:
(parameterList) {
// Function body
};
Example: Anonymous Function Assigned to a Variable
var add = (int a, int b) {
return a + b;
};
print(add(5, 3)); // Output: 8
4. Collections
List
var nums = [1, 2, 3];
List nums=[1,3,4];
List <int>nums=[5,8,9];
Set
var items = {'apple', 'banana'};
items.add('orange');
print(items.contains('banana'));
Map
var person = {'name': 'John', 'age': 25};
print(person['name']);
person['height'] = 5.9;
MAPS:
5. Classes and Objects
class Person {
String name;
int age;
Person(this.name, this.age);
void greet() {
print("Hi, I'm $name!");
}
}
Point(this.x, this.y);
Point.origin() : x = 0, y = 0;
}
Abstract Classes: Cannot be instantiated directly. They act as a blueprint for other classes.
dart
Copy code
abstract class Animal {
void speak(); // Abstract method
}
Sealed Classes: Restrict subclassing to only certain classes within the same file.
dart
Copy code
sealed class Animal {
void speak();
}
○
● Use of this:
○ Refers to the current instance of the class.
○ Commonly used to refer to instance variables or call instance methods.
dart
Copy code
class Person {
String name;
Person(this.name);
void greet() {
print("Hello, ${this.name}!");
}
}
●
● Constructor Types:
○ Default Constructor: Automatically provided if no constructors are defined.
○ Named Constructor: Custom constructor with a name.
○ Factory Constructor: Allows custom logic for instance creation.
dart
Copy code
class MyClass {
MyClass.namedConstructor();
}
dart
Copy code
final class Animal {
void speak() {
print("Animal speaks");
}
}
●
● const:
○ Used to define compile-time constants.
○ Classes with a const constructor are used to create immutable objects.
dart
Copy code
class Point {
final int x, y;
const Point(this.x, this.y);
}
●
● abstract:
○ A class that cannot be instantiated but can be inherited from.
○ Can contain abstract methods (no implementation).
dart
Copy code
abstract class Animal {
void speak(); // Abstract method
}
●
● mixin:
○ A special class that can be reused in multiple classes without using inheritance.
○ Used for code sharing between classes.
dart
Copy code
mixin Swimmer {
void swim() {
print("Swimming...");
}
}
●
● implements:
○ Forces a class to implement all methods from an interface (a class can act as an
interface).
dart
Copy code
class Animal {
void speak();
}
●
● extends:
○ Used for inheritance, where a child class inherits from a parent class.
dart
Copy code
class Animal {
void speak() {
print("Animal speaks");
}
}
●
● static:
○ Defines class-level properties or methods, not dependent on instances.
dart
Copy code
class Counter {
static int count = 0;
static void increment() {
count++;
}
}
●
● factory:
○ Custom constructor that doesn't necessarily create a new instance every time
(e.g., singleton pattern).
dart
Copy code
class Database {
static final Map<String, Database> _cache = {};
Database._internal(String name);
● }
● Getters and Setters are special methods used to access and modify an object's
properties.
Getters
dart
Copy code
class Person {
void main() {
● Key Points:
○ Use get followed by the property name.
○ The getter method returns the value of the field but doesn’t require calling it like a
function (i.e., no parentheses).
Setters
Syntax:
dart
Copy code
class Person {
void main() {
● Key Points:
○ Use set followed by the property name.
○ The setter method assigns a value to the field and allows modification of the
private property.
dart
Copy code
class Person {
String _name;
Person(this._name);
// Getter
// Setter
if (value.isNotEmpty) {
_name = value;
} else {
void main() {
}
● Key Points:
○ Getters are used for accessing the value.
○ Setters are used for modifying the value, often with validation.
6. Async Programming
1. Stream
Example:
dart
Copy code
Stream<int> counterStream() async* {
for (var i = 0; i < 5; i++) {
yield i; // Send data at each iteration
await Future.delayed(Duration(seconds: 1));
}
}
2. StreamController
Example:
dart
Copy code
StreamController<int> controller = StreamController<int>();
void main() {
controller.stream.listen((data) {
print(data); // Prints: 10
});
3. StreamSubscription
Example:
dart
Copy code
Stream<int> counterStream() async* {
for (var i = 0; i < 5; i++) {
yield i;
await Future.delayed(Duration(seconds: 1));
}
}
void main() {
var subscription = counterStream().listen((data) {
print(data); // Prints 0, 1, 2, 3, 4
});
Future.delayed(Duration(seconds: 3), () {
subscription.cancel(); // Cancels the subscription after 3
seconds
});
}
4. StreamTransformer
● StreamTransformer allows you to transform the data from one stream into another
type, e.g., converting Stream<int> to Stream<String>.
Example:
dart
Copy code
Stream<int> numbers() async* {
yield 1;
yield 2;
yield 3;
}
● async*: Used to create a stream-producing function. It works like async but yields
multiple values over time.
● yield: Used to send values in an asynchronous generator function.
Example:
dart
Copy code
Stream<int> generateNumbers() async* {
yield 1;
yield 2;
yield 3;
}
6. Stream.listen()
Example:
void main() {
numbers().listen((data) {
print(data); // Prints: 10, 20, 30
});
}
7. Exception Handling
Try-Catch
dart
Copy code
try {
int result = 12 ~/ 0;
} catch (e) {
print("Error: $e");
} finally {
print("Done!");
}
Throwing Exceptions
dart
Copy code
void checkAge(int age) {
if (age < 18) throw Exception("Too young!");
}
8. Useful Features
Spread Operator
dart
Copy code
var list = [1, 2, 3];
var extended = [...list, 4, 5];
Cascade Notation
dart
Copy code
var buffer = StringBuffer()
..write("Hello")
..write(" World!");
print(buffer.toString());
Type Checking
dart
Copy code
if (person is String) {
print("Person is a String");
}
9.Enums
● Fixed Set: Enums are used to define a group of related constants that don't change.
● Improves Code Readability: They make your code more readable by using descriptive
names for constant values.
● Type Safety: They provide better type safety by restricting values to the defined set.
Example of an Enum:
dart
Copy code
enum Day {
monday,
tuesday,
wednesday,
thursday,
friday,
saturday,
sunday
}
void main() {
printDay(Day.monday); // Prints: Start of the week!
printDay(Day.friday); // Prints: Almost weekend!
}
Benefits:
Enum Methods:
enum Day {
monday,
tuesday,
wednesday,
}
void main() {
print(Day.monday.index); // Prints: 0 (index of monday)
print(Day.tuesday.toString()); // Prints: Day.tuesday (name of the
enum)
}