Download as pdf or txt
Download as pdf or txt
You are on page 1of 16

flutterawesome.

com /a-quick-reference-for-dart-language-concepts-syntax-and-usage/

A quick reference for Dart language concepts, syntax, and


usage
Flutter Awesome ⋮ ⋮ 5/4/2023

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 the main function as an asynchronous function, and the await
keyword is used to pause the execution of the function until the delayedHello() 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.

GitHub
View Github

You might also like