Dart - tutorial - before Flutter project

Before starting Flutter project , Dart basic!

·

7 min read

var

Dart declares variables similarly to Java, but unlike Java, type inference is possible.

var friend = 'taelab';
friend = 23; // Error: Compilation failed.

By the way, Dart also has a dynamic type that can change its type.

dynamic

In the case of dynamic, the type can be inferred like var, and the type can also be changed. In addition, since dynamic is supported in parameters, there is no need to specify the type.

dynamic a= 'tae';
a= 121342;

Type casting and num

In Java, large types are automatically type-casted without explicitly type-casting small types, but in the case of Dart, type-casting is required.

int n = 2;
// Error: Compilation failed.
double m = n; 

int n = 1;
double m = n as double; //ok

In the case of int and double, they can also be declared as supertype num.

num a = 1;
num b = 1.11;

final / const

In common, both final and const cannot be changed once declared. A value defined as final can be set as a value defined at runtime, but a value defined as const cannot be set as a value defined at runtime.

Collections

Dart provides collections such as List, Map, and Set, but does not provide an array data structure.

// List
List<int> setNums = [1,2,3,4,5];
var nums2 = [1, 2, 3]; // Type inferred
var nums3 = [1, 2, 3 ,4, if (true) 5]; //condition in List
var friends = ['a','b','c'];
var new_friends = ['d','e','f', for (var friend in friends ) "- ${friend}"];


// set
Set<int> setNums = {1,2,3,4,4,4,4,66,6};
var setNums2 = {1,5,5,4,6,4,3,3,5,5,5,1,5,5,2,2,2}; // Type inferred



// map
Map<String, int> mapNums = {
  "key" : 1,
  "key2" : 2
};
var mapNums2 = {  // Type inferred
  "key" : 1,
  "key2" : 2
};

var nums = {

}

When declaring set and map through var, if nothing is written inside {}, var is inferred as map type.

Spread operator ...

  // (...)
  var a = [1,2,3,4,6];
  var b = [...a, 5, 7];

function declaration

Since the type of the parameter is inferred as dynamic, there is no need to specify the data type.

add(num1, num2){

  return num1 + num2;
}

optional parameter

Optional parameters allow optional use of parameters wrapped in {} when defining a function.

add(num1, {num2}){

  return num1 + num2;
}

print(add(1, num2 : 3));

If you want to return a value other than null as for optional parameter, you can give it a default value.

add(num1, {num2 = 3}){

  return num1 + num2;
}

function and QQ operator

// name parameter can be null.
String capitalizeName(String? name) => name != null 
? name.toUpperCase() : 'ANON'
String capitalizeName(String? name) => name?.toUpperCase() ?? 'ANON'

QQ operator

void main () {
    String? name;
    name ??= 'a';
    name ?? ='another';
    print(name); // a
}

Asynchronous processing - Future, async, await

A Future promises to receive the result of a certain task later, and proceeds to the next task immediately without waiting for the result of the requested task. After that, when the task is completed, the asynchronous processing is executed by receiving the result value.

void main(){

  print("start");
  asyncFunc();
  print("end");
}


Future asyncFunc() async{

  await Future.delayed(Duration(seconds : 1));
  print("1");

  await Future.delayed(Duration(seconds : 1));
  print("2");

  await Future.delayed(Duration(seconds : 1));
  print("3");

  return;
}

Class

class Person {
  final String name = 'tat';
  int age;

  getName(){
    return name;
  }
    Person (String name, int age) {
        this.name = name; // error since final String field
         this.age = age;

    }

}
class Person {
  late final String name = 'tat';
    //late means that the values of the variables will be retrieved later.
  late int age; 

  getName(){
    return this.name;
  }
    Person (String name, int age) {
        this.name = name; 
         this.age = age;

    }

}
void main () {
    var person = Person ("taesik", 22);

}

Brief constructor + specified parameter + required

class Player {
    final String name;
    int age;
    String team;
    int point;

    Player({
        required this.name,
        required  this.age,
        required this.team,
        required this.point,
    });


    void greet() {
        print('Hi my name is $name');

    }

}

void main() {
    //specified parameter key-value style 
    var player = Player (
        name:"asd",
        age: 22,
        team: 'pncst',
        point: 20000,
    )
}

Brief field

class Player {
    final String name,  team;
    int age,point;


    Player({
        required this.name,
        required  this.age,
        required this.team,
        required this.point,
    });


    void greet() {
        print('Hi my name is $name');

    }

}

void main() {
    //specified parameter key-value style 
    var player = Player (
        name:"asd",
        age: 22,
        team: 'pncst',
        point: 20000,
    )
}

late means that the values of the variables will be retrieved later.

Java uses the new keyword when creating an object, but Dart basically omits it.

The same role as Private in Java, but in Dart, Private is defined by appending _. In Java, private can be accessed only within the class, but in Dart, private variables can be accessed in the file where the class is defined.

Named Constructors

class Player {
    final String name,  team;
    int age,point;


    Player( {
        required this.name,
        required this.age,
        required this.team,
        required this.point,
    }
    );
    Player.createBluePlayer({
        required String name,
         required int age
    }) :    this.age = age,
            this.name = name,
            this.team = 'blue',
            this.xp = 0; 

    Player.createRedPlayer(String name, int age) 
    : this.age =age,
    this.name = name,
    this.team = 'red',
    this.xp =0;

    void greet() {
        print('Hi my name is $name');

    }

}

void main() {
    //specified parameter key-value style 
    var player = Player (
        name:"asd",
        age: 22,
        team: 'pncst',
        point: 20000,
    )

    var player1 = Player.createBluePlayer(
        name: 'brian',
        age:21,
    );
    var redplayer = Player.createRedPlayer('tasdi',21);

}

Cascade Notation

class Player {
    final String name,  team;
    int age,point;


    Player( {
        required this.name,
        required this.age,
        required this.team,
        required this.point,
    }
    );
    Player.createBluePlayer({
        required String name,
         required int age
    }) :    this.age = age,
            this.name = name,
            this.team = 'blue',
            this.xp = 0; 

    Player.createRedPlayer(String name, int age) 
    : this.age =age,
    this.name = name,
    this.team = 'red',
    this.xp =0;

    void greet() {
        print('Hi my name is $name');

    }

}

void main() {
    var taesik = Player(name: 'taesik', point:1000, age:22,team:'ada')
    ..name = 'asd'
    ..xp = 1200000
    ..team = 'blue';

    var ted = Player(name: 'taesik', point:1000, age:22,team:'ada');
    var clone = ted
    ..name = 'clone'
    ..xp = 12222
    ..team = 'blue'
    ..greet();
}

enums

enum Team {red,blue}

// 
Team.blue
TEam.red

abstract class, abstract method

abstract class Human {
    void walk;

}
class Player extends Human {
    void walk() {
        ...
    }
 ...

Inheritance + override method

class Human {
    final String name;
    Human(this.name);
    void greet() {
        print('hello');
    }
}
enum Team {red,blue}

class Player extends Human {
    final Team team;
    Player({
        required this.team,
        required String name, //Forwarding to Human class
    }) : super(name:name);

    @override
    void sayHello(){
        super.sayHello();
        print('and I want to win ${team}');
    }
...

Mixins - (Class without constructor)

class Point {
    final double level = 12121;

}
class QuickPlayer {
    void doSomethingQuick() {

    }
}

class Player with Point, QuicPlayer {
    ...
}

null safety - nullable, non-nullable

int a = 10;
a = null; // Error: Compilation failed.

int? h = 10;
h = null; // ok

A var type cannot be declared nullable. As explained above, type inference is possible for var types, so nullable and non-nullable are automatically inferred.

Null safety in dynamic types is meaningless. The dynamic type means that the value to be assigned is not limited, and all types of data can be assigned. Since all of these types also include nullable, being declared as a dynamic type is itself declared as nullable.

Type check - 'is'

  int a = 1;
  print(a is int); //true
  print(a is! int); //false

anonymous function

(number) {
return number % 2 == 0;
};

Lambda

(number) => number%2 == 0;

typedef (type variable)

typedef listOfInts = List<int>;

listOfInts reverseListOfNumbers(listOfInts  list) {
    var reversed = list.reversed;
    return reversed.toList(); 
}