Dart Tutorial

Dart Tutorial Single-Page Application Architecture Dart Features Dart Installation Guide Dart Basic Program Dart Syntax Dart Keywords Dart Variables Dart Comments Dart Standard Input Output Dart Important Concepts

Data Types

Built-in Data Types Numbers Strings Booleans Lists Sets Maps Runes and Graphemes Symbols Enumerations Constants Queues

Other data types

Objects Future and stream Iterable Miscellaneous types

OPERATORS

Precedence and associativity Arithmetic operators Equality and Relational operators Type Test Operators Assignment Operators Logical Operators Bitwise and Shift Operators Miscellaneous operators

Control Flow Statements

Introduction If statement If-else statement If-else-if statement Loops Switch and case Dart Break And Continue Assert In Dart

FUNCTIONS

Dart function Types of Functions Anonymous function main( ) function Lexical scope and closure Recursion Common Collection Methods

Object Oriented Concepts

Dart Object-Oriented Concepts Dart Classes Dart Constructors Dart This Keyword Dart Super Keyword Static Members Method Overriding Dart Interfaces Inheritance Dart Abstract Classes Dart Builder Classes Dart Callable Classes

Dart Type System

Dart Type System Dart Soundness Dart Type Inference

MISCELLANEOUS

Dart Isolates Dart Typedef Dart Metadata Dart Packages Dart Generics Dart Generators Dart Concurrency Dart Unit Testing Dart Html Dom Dart URIs Dart Extends, With and Implements Keywords Dart Optional Parameters Rust Vs Dart C++ vs Dart Golang Vs Dart Dart Basics Exception Handling

Dart Anonymous Function

Dart functions are the user defined functions that are designed to perform specific task. The use case of the functions is that they can be directly called any number of times in a program wherever required without having to write the same lines of code again and again. So far, we have understood the named user-defined functions. But Dart also supports the nameless functions i.e., the functions that do not have any name. Such functions are also known as anonymous functions, lambda functions or closure.

Anonymous functions have similar features to the regular function with the only difference of it not having name. They can have either no arguments or any number of arguments with an optional type annotation. They can be assigned to a variable and then the value of closure can be retrieved or accessed as per the need. They contain an independent block of the code, which can be passed around in our code as function parameters. The syntax is as follows.

Syntax :

( parameter_list ) {  

   statement( s ) 

}

Let's consider the following example.

Program

void main( ) 

{   

  var list = [ " Yukta ", " Tushar ", " Divya ", " Atharva " ] ; 

  print( " Example of anonymous function " ) ; 

  list.forEach( ( item ) { 

      print( ' ${ list.indexOf( item ) } : $item ' ) ; 

} ) ;   

Output :

Example of anonymous function

0 :  Yukta

1 :  Tushar

2 :  Divya

3 :  Atharva

Explanation:

The above example lists a user defined anonymous function with a single type argument 'item'. This function called for each and every time in the list and printed the strings initialized in the list with its specified index value.

If we were to confine the function in just one statement, then the above code could be written as follows :

list.forEach(  ( item ) => print( " ${ list.indexOf( item ) } : $item " ) ) ; 

This code is pretty much equivalent to this above snippet. It can be verified by pasting it in the above Dart code and compile.

Lexical Scope

The lexical scope is a term used in various programming languages that describes a condition where the scope of the variable is not present when the control is out of the block of the code where the scope was present just now.

Dart is a lexically scoped language. The scope of the variable is decided at the time of compilation. The variable behaves differently if defined in the different curly braces. In order to determine the scope of the variable, trace all the braces and stop where that variable exists.

Let's understand the lexical scope using the following example.

Program

/* declaring a global variable that is outside the all functions

It can be accessed throughout the whole program */

var global = 10 ;




void main( ) {

  /* this is the local variable to the function main( )

   It is accessible only within the main( ) function. */

  var local = 5;




  print(global);

  print(local);

 

  void func( ) {

   /* this is the local variable to the function func( )

   It is accessible within the function func( ) and func1( ). */

    var func_var = 1;

    print(func_var);

    print(local);

    print(global);

 

    void func1( ) {

    /* this is the local variable to the function main( )

     It is accessible within the function func1( ) and func( ). */

      var func1_var = 2;

      print(func1_var);

      print(func_var);

      print(local);

      print(global);

      }

  }

}

Output:

10

5

Lexical Closure

A lexical closure is a way by which we implement lexical scope name binding in a function. It is a function object that has access to variables in its lexical scope even when the function is used of its original scope. In other words, it provides access to an outer function's scope from the inner function. Let's understand the following example.

Program

/* a function that accepts the value of local from 

main( ) and prints it */

void func(int local ) {

   

    var func_var = 1 ;

    print( func_var ) ;

    print( local ) ;

  }

 

void main( )

{

  // initializing the local variable with value 5

  var local = 5 ;




  func( local ) ;

}

Output:

1

5