Dart CookBook: Keywords and their usage.
Published: 2024-04-12 18:40:21

1. **abstract**: Used to declare abstract classes. Abstract classes cannot be instantiated directly.
    
    ```dart
    //Declaration
    abstract class SubClass {}
    
    //Usage
    class MainClass extends SubClass{}
    ```
    
2. **as**: Used for typecasting to a type.
    
    ```dart
    dynamic dynamicInt = 0;
    
    //Usage 
    int realInt = (dynamicInt as int);
    ```
    
3. **assert**: Used for validation purposes to check the truthfulness of a boolean expression. If the expression is false, an AssertionError is thrown.
    
    ```dart
    int x = 10;
    
    // Asserts that the value of x is greater than 0.
    assert(x > 0);
    ```
    
4. **async**: Used to define asynchronous functions. An asynchronous function returns a Future or Stream object and can use the await keyword inside it.
    
5. **await**: Used inside asynchronous functions to pause execution until a Future completes.
    
    ```dart
      //function of future
      Future<void> delayFunc() async {
    
        //this future will be awaited
        await Future.delayed(Duration(seconds: 1));
    
        return null;
      }
    ```
    
6. **break**: Used to exit the innermost loop or switch statement.
    
    ```dart
      List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
      
      // Iterating through the list of numbers
      for (int number in numbers) {
        print('Current number: $number');
        
        // If the number is greater than 5, exit the loop
        if (number > 5) {
          print('Number is greater than 5. Exiting loop.');
          break; // Exiting the loop
        }
        
        // This line will be executed for numbers less than or equal to 5
        print('Number is less than or equal to 5.');
      }
    ```
    
7. **case**: Used in switch statements to specify different cases for comparison.
    
    ```dart
     String fruit = 'apple';
    
      switch (fruit) {
        case 'apple':
          break;
        case 'banana':
          break;
        default:
          print('Selected fruit is not in the list.');
      }
    ```
    
8. **catch**: Used to catch exceptions in try-catch blocks.
    
    ```dart
    try {
    //perform your actions here
    } catch (error){
    //do anything with the error here
    }
    ```
    
9. **class**: Used to declare a class.
    
    ```dart
    class ClassName {}
    ```
    
10. **const**: Used to define compile-time constant values.
    
    ```dart
    const int value = 0;
    ```
    
11. **continue**: Used to skip the rest of the loop body and continue to the next iteration of the loop.
    
    ```dart
    List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
      // Iterating through the list of numbers
      for (int number in numbers) {
        // If the number is even, skip it and continue with the next iteration
        if (number % 2 == 0) {
          continue; // Skip to the next iteration
        }
    
        // This line will be executed only for odd numbers
        print('Processing odd number: $number');
      }
    ```
    
12. **covariant**: Used to declare that a subclass can override a method with a parameter of a different type.
    
13. **default**: Used in switch statements to specify the default case.
    
    > *Example can be seen in item 7 (case).*
    
14. **deferred**: this is used in combination with the `import` statement to lazily load a library when it's first accessed. This can be useful for optimizing performance by deferring the loading of large libraries until they are needed.
    
    ```dart
    import 'dart:async';
    import 'dart:math' deferred as math;
    
    Future<void> loadMathLibrary() async {
      await math.loadLibrary();
      print('Math library loaded.');
      
      double squareRoot = math.sqrt(25);
      print('Square root of 25: $squareRoot');
    }
    
    void main() {
      print('Before loading math library.');
    
      loadMathLibrary();
    
      print('After loading math library.');
    }
    ```
    
15. **do**: Used to start a do-while loop.
    
    ```dart
     int count = 0;
    
      //This loop will continue until count is 5
      do {
        count++;
      } while (count < 5);
    ```
    
16. **dynamic**: Used to declare variables with dynamic type, where the type is determined at runtime.
    
    ```dart
    //dynamic represents any datatype including null
    dynamic value = "Odinachi";
    ```
    
17. **else**: Used in if-else statements to specify the block of code to execute if the condition is false.
    
    ```dart
    bool value = false;
    //else block will be executed because value is equal to false
    if (value){
      print("value is true");
    } else {
       print("value is is false");
    }
    ```
    
18. **enum**: Used to declare enumerated types.
    
    ```dart
    //Declaration
    enum Weekday {
      Monday,
      Tuesday,
      Wednesday,
      Thursday,
      Friday,
      Saturday,
      Sunday
    }
    
    //usage
    Weekday today = Weekday.Tuesday;
    ```
    
19. **extends**: Used to create a subclass that inherits from a superclass.
    
    ```dart
    // Define a superclass called 'Animal'
    class Animal {
      String name;
      
      // Constructor
      Animal(this.name);
      
      // Method to make sound
      void makeSound() {
        print('Animal $name makes a sound');
      }
    }
    
    // Define a subclass called 'Dog' that extends 'Animal'
    class Dog extends Animal {
     /* 
        we can get what parameters we need for the Dog class and also
        pass the required parameters for Animal class as well inside the super 
        implementation
      */
      Dog(String name) : super(name);
      
      // We want to chnage what sound dog makes
      @override
      void makeSound() {
        print('Dog $name barks');
      }
      
      // Method specific to Dog class
      void wagTail() {
        print('Dog $name wags its tail');
      }
    }
    
    ```
    
20. **extension**: Used to add new functionality to existing classes without modifying their source code.
    
    ```dart
    extension StringExtensions on String {
      // Method to convert a string to title case
      String toTitleCase() {
        return this.split(' ')
            .map((word) => word.isEmpty
                ? '' // Handle empty strings
                : word[0].toUpperCase() + word.substring(1).toLowerCase())
            .join(' ');
      }
    }
    
    //usage
    String message = 'hello world';
    String titleCaseMessage = message.toTitleCase();
    ```
    
21. **factory**: constructor is a special type of constructor used to create objects. Unlike a regular constructor, a `factory` constructor does not always create a new instance of its class. It may return an existing instance, a subclass instance, or even an instance of a different class altogether. This flexibility makes `factory` constructors useful for implementing object creation logic that cannot be achieved with regular constructors alone.
    
    ```dart
    //Example one
    class Point {
      final int x;
      final int y;
    
      // Private constructor
      Point._(this.x, this.y);
    
      // Factory constructor to create Point objects
      factory Point(int x, int y) {
        // Check if the coordinates are valid
        if (x >= 0 && y >= 0) {
          // If valid, return a new Point object
          return Point._(x, y);
        } else {
          // If invalid, return a default Point object
          return Point._(0, 0);
        }
      }
    
      @override
      String toString() {
        return 'Point(x: $x, y: $y)';
      }
    }
    
    
    
    //Example two 
    class Point {
      final int x;
      final int y;
    
      Point(this.x, this.y);
    
      factory Point.fromJson(Map<String, dynamic> json) {
        return Point(
          json['x'] as int ?? 0, // If 'x' is not present or not an integer, default to 0
          json['y'] as int ?? 0, // If 'y' is not present or not an integer, default to 0
        );
      }
    
      @override
      String toString() {
        return 'Point(x: $x, y: $y)';
      }
    }
    ```
    
22. **false**: Boolean literal representing the false value.
    
23. **final**: Used to declare variables whose values cannot be changed once initialized.
    
    ```dart
    final int value = 10;
    ```
    
24. **finally**: Used in try-catch-finally blocks to specify code that should always be executed, regardless of whether an exception is thrown.
    
    ```dart
    try {
        // Perform some operation that may throw an exception
      } catch (e) {
        // Handle the exception
      } finally {
        // This will always be executed
      }
    ```
    
25. **for**: Used to start a for loop.
    
    ```dart
     for (int i = 0; i < 5; i++) {
        print('Iteration $i');
      }
    ```
    
26. **Function**: Used as a type annotation for function types.
    
    ```dart
    //int here represents the return type
    int functionName(){
       return 0;
    }
    ```
    
27. **get**: Used to define getter methods for retrieving the value of a class property. Getters are used to access the value of a property without directly accessing the underlying data member.
    
    ```dart
    class Rectangle {
      double _width; 
      double _height;
    
      // Constructor
      Rectangle(this._width, this._height);
    
      // Getter for the width property
      double get width => _width;
    
      // Getter for the height property
      double get height => _height;
    
      // Getter for the area property
      double get area => _width * _height;
    }
    ```
    
28. **hide**: Used in combination with the `import` directive to specify that certain members of a library should not be made available to the importing code.
    
    ```dart
    import 'package:flutter/material.dart' hide MaterialApp;
    ```
    
29. **if**: Used to start an if statement.
    
    > *Example can be seen in item 17 (else).*
    
30. **implements**: Used to declare that a class implements a set of methods specified by an abstract class.
    
    ```dart
    // Define an abstract calss called 'Shape'
    abstract class Shape {
      double area(); // Abstract method
    }
    
    // Define a class called 'Rectangle' that implements the 'Shape' interface
    class Rectangle implements Shape {
      double width;
      double height;
    
      // Constructor
      Rectangle(this.width, this.height);
    
      // Implement the 'area' method required by the 'Shape' interface
      @override
      double area() {
        return width * height;
      }
    }
    ```
    
31. **import**: Used to import libraries into the current Dart file.
    
    ```dart
    import 'package:flutter/material.dart';
    ```
    
32. **in**: Used within collection literals (such as lists, sets, and maps) to check if an element exists in the collection. This is often used in conjunction with the `for` loop to iterate over the elements of a collection.
    
    ```dart
    //Checking if an element exist
    List<int> numbers = [1, 2, 3, 4, 5];
      // Check if an element exists in the list
      if (3 in numbers) {
        print('3 is present in the list');
      } else {
        print('3 is not present in the list');
      }
    
    //Control flow
    List<String> fruits = ['Apple', 'Banana', 'Orange'];
      // Iterate over the elements of the list using for-in loop
    for (String fruit in fruits) {
       print('Fruit: $fruit');
     }
    ```
    
33. **is**: to check whether an object is an instance of a particular class or implements a particular abstract class.
    
    ```dart
    dynamic value = 0;
    
    //we're check if value is an integer
    if(value is int){
      print(value);
    }
    
    //can also be used for error handling
    try{
    //operations
    } catch (error) { 
    //you can check what type of error it is.
    if(error is TypeError){
    //perform some operations
        } 
    }
    ```
    
34. **late**: Used to declare variables that are initialized at a later point, allowing you to defer initialization until it's needed. This is particularly useful for non-nullable variables that can't be assigned `null` initially but are initialized before being accessed
    
    ```dart
    class className {
      late final String value;
    
      void getVal() {
        //value must be assisgned before being referenced
        value = "Odinachi";
        print(value);
      }
    }
    ```
    
35. **mixin**: Used to define mixins, which are a way to reuse a class's code in multiple class hierarchies.
    
    ```dart
    mixin MixinName {
      //Methods
    }
    class ClassName with MixinName {}
    ```
    
36. **null**: Represents the null object.
    
    ```dart
    int? value = null;
    ```
    
37. **on**: Used in catch clauses to specify the types of exceptions to catch in a `try-catch` block.
    
    ```dart
    try {
        //operation
      } on IntegerDivisionByZeroException {
        //IntegerDivisionByZeroException can be any exception type
      } catch (e) {
        // Catching any other type of exception
      }
    ```
    
38. **part**: to split a library into multiple files. This allows you to organize and manage large codebases more effectively by dividing them into smaller, more manageable parts.
    
    ```dart
     part 'file_name.dart';
    
    // NB: the corresponding file must have:
    part of "filename_above.dart";
    
    /* part must come after the import statement and the "part of" file
    doesn't contain any imports as all the imports are done on the 
    part file */
    ```
    
39. **rethrow**: Used in catch blocks to rethrow the caught exception.
    
    ```dart
    try {
        // operations
      } catch (e) {
        // Catching any exception thrown during the division operation
       
        // Rethrowing the caught exception
        rethrow;
      }
    ```
    
40. **return**: Used to return a value from a function/method.
    
    ```dart
    int value(int a, int b){
       return a + b;
    }
    ```
    
41. **set**: Used to define setter methods.
    
    ```dart
    class ClassName {
      String _name; // Private instance variable
    
      // Setter for the 'name' property
      set name(String value) {
       _name = value; // Assign value to '_name' if it's not null or empty
      }
    
      // Getter for the 'name' property
      String get name => _name;
    }
    ```
    
42. **show**: Used in import statements to only import specific members of a library.
    
    > This is the opposite of hide in item 28 (hide)
    
43. **static**: Used to declare static variables or methods in a class.
    
    ```dart
    class ClassName {
       static int value = 0;
       void call(){}
    }
    
    //usage
    int number = ClassName.value;
    ClassName.call();
    //NB: classed do not have to be instantiated to access their static variables
    ```
    
44. **super**: Used to refer to the superclass of the current class.
    
    > Example can be seen on item 19 (extends)
    
45. **switch**: Used to start a switch statement.
    
    > Example can be seen on item 7 (case)
    
46. **this**: Used to refer to the current instance of a class from within its methods or constructors. It is commonly used to access instance variables, invoke other methods, or pass the current instance to other functions.
    
    ```dart
    class ClassName {
        final value = 0;
    
        int getVal(){
    //0 will be returned because the value of value on this instance of class name is 0
            return this.value;
        }
    }
    ```
    
47. **throw**: Used to throw exceptions.
    
    ```dart
    void validateAge(int age) {
      if (age < 0) {
        throw ArgumentError('Age cannot be negative');
      }
    }
    ```
    
48. **true**: Boolean literal representing the true value.
    
49. **try**: Used to start a try block for exception handling.
    
    > Example can be seen on item 8 (catch)
    
50. **typedef**: Used to define function type aliases.
    
    ```dart
    // Define a typedef for a function that takes two integers and returns an integer
    typedef MathOperation = int Function(int a, int b);
    
    // Function to perform addition
    int add(int a, int b) {
      return a + b;
    }
    
    // Declare a variable of type MathOperation and assign the 'add' function
    MathOperation operation = add;
    
    // Use the variable to perform addition
    int result = operation(5, 3);
    print('Result of addition: $result'); // Output: Result of addition: 8
    ```
    
51. **var**: Used to declare variables without specifying their type explicitly.
    
    ```dart
    var value = "Odinachi";
    ```
    
52. **void**: Used to specify that a function does not return any value.
    
    ```dart
    void doSomething{
        //perform some operations
        return null;
    }
    ```
    
53. **while**: Used to start a while loop.
    
    ```dart
     int count = 0;
      // While loop to print numbers from 1 to 5
      while (count < 5) {
        count++;
        print('Number: $count');
      }
    //NB: the loop won't break for as long as the condition is true
    ```
    
54. **with**: Used to specify mixins that a class uses.
    
    > Example can be seen on item 35 (mixins)
    
55. **yield**: Used inside generator functions to produce a value for each iteration.
    
    ```dart
    Iterable<int> generateNumbers(int n) sync* {
      for (int i = 1; i <= n; i++) {
        yield i; // Yielding values from 1 to n
      }
    }
    
     var numbers = generateNumbers(5);
    ```