## 入门

### 安装 Dart

#### Windows

    C:\> choco install dart-sdk # Windows

#### Linux

执行以下一次性设置

    $ sudo apt-get update
    $ sudo apt-get install apt-transport-https
    $ wget -qO- https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo gpg --dearmor -o /usr/share/keyrings/dart.gpg
    $ echo 'deb [signed-by=/usr/share/keyrings/dart.gpg arch=amd64] https://storage.googleapis.com/download.dartlang.org/linux/debian stable main' | sudo tee /etc/apt/sources.list.d/dart_stable.list

安装 Dart SDK

    $ sudo apt-get update
    $ sudo apt-get install dart

#### Mac

    $ brew tap dart-lang/dart
    $ brew install dart

### hello.dart

    // 应用执行开始的顶级函数
    void main() {
        print("Hello World!"); // 打印到控制台
    }

每个应用程序都有一个 `main()` 函数

#### Windows

    $ dart compile exe hellow.dart
    $ time ./hello.exe
    Hello World!

### 变量

    int x = 2; // 显式键入
    var p = 5; // 类型推断 - 具有类型推断的通用var
    dynamic z = 8; // 变量可以采用任何类型
    z = "cool"; // cool

    // 如果您从不打算更改变量，请使用 final 或 const
    // 像这样的东西：
    final email = "temid@gmail.com";
    // 与 var 相同，但不能重新分配
    final String email = "temid@gmail.com";
    // 你不能改变价值
    const qty = 5; // 编译时常数

### 数据类型

    // 整数，范围 -2^63 到 2^63 - 1
    int age = 20;
    // 浮点数字

    double height = 1.85;
    // 您还可以将变量声明为 num
    // x 可以同时具有 int 和 double 值
    num x = 1;
    num += 2.5;
    print(num); // 打印: 3.5

    String name = "Nicola";
    bool isFavourite = true;
    bool isLoaded = false;

### 注释

    // 这是一条正常的单行注释
    /// 这是一个文档注释，用于文档库，
    /// 类及其成员。 IDE 和 dartdoc 等工具
    /// doc 特别注释。
    /* 也支持此类注释 */

### 字符串插值

    // 可以对字符串类型使用单引号或双引号
    var firstName = 'Nicola';
    var lastName = "Tesla";
    // 可以用 $ 将变量嵌入到字符串中
    String fullName = "$firstName $lastName";
    // 与 + 连接
    var name = "Albert " + "Einstein";
    String upperCase = '${firstName.toUpperCase()}';
    print(upperCase); // 打印: NICOLA

### 导入 Imports

    // 导入核心库
    import 'dart:math';
    // 从外部包导入库
    import 'package:test/test.dart';
    // 导入文件
    import 'path/to/my_other_file.dart';

## 操作符

### 算术运算符

    print(2 + 3);  // 打印: 5
    print(2 - 3);  // 打印: -1
    print(2 * 3);  // 打印: 6
    print(5 / 2);  // 打印: 2.5 - 结果是 double
    print(5 ~/ 2); // 打印: 2 - 结果是n int
    print(5 % 2);  // 打印: 1 - 余
    int a = 1, b;

    // 增
    b = ++a; // 前增量 - 在 b 获得其值之前增加 a
    b = a++; // 后增量 - 在 b 获得它的值之后增加 a
    // 递
    b = --a; // 前减量 - 在 b 获得它的值之前减少 a
    b = a--; // 后减量 - 在 b 获得它的值之后递减 a

### 逻辑运算符

    // !expr 反转表达式（将 false 更改为 true，反之亦然）
    // ||  逻辑或
    // &&  逻辑与
    bool isOutOfStock = false;
    int quantity = 3;
    if (!isOutOfStock && (quantity == 2 || quantity == 3)) {
      // ...Order the product...
    }

### 等式和关系运算符

    print(2 == 2); // 打印: true - 平等的
    print(2 != 3); // 打印: true - 不相等
    print(3 > 2);  // 打印: true - 比...更棒
    print(2 < 3);  // 打印: true - 少于
    print(3 >= 3); // 打印: true - 大于或等于
    print(2 <= 3); // 打印: true - 小于或等于

## 控制流：条件

### if 和 else if

    if(age < 18){
        print("Teen");
    } else if( age > 18 && age <60){
        print("Adult");
    } else {
        print("Old");
    }

### switch case

    enum Pet {dog, cat}
    Pet myPet = Pet.dog;
    switch(myPet){
        case Pet.dog:
            print('My Pet is Dog.');
            break;
        case Pet.cat:
            print('My Pet is Cat.');
            break;
        default:
            print('I don\'t have a Pet');
    }
    // 打印: My Pet is Dog.

## 控制流：循环

### while 循环

    while (!dreamsAchieved) {
      workHard();
    }

循环迭代之前的 `while` 循环检查条件

### do-while 循环

    do {
      workHard();
    } while (!dreamsAchieved);

`do-while` 循环在执行循环内的语句后验证条件

### for 循环

    for(int i=0; i< 10; i++){
        print(i);
    }
    var numbers = [1,2,3];
    // 列表的 for-in 循环
    for(var number in numbers){
        print(number);
    }

## Collections

### Lists

    // 有序的对象组
    var list = [1, 2, 3];
    print(list.length); //Print: 3
    print(list[1]); //Print: 2
    // 列表声明和初始化的其他方式
    List<String> cities = <String>["New York", "Mumbai", "Tokyo"];
    // 创建一个编译时常量的列表
    const constantCities = const ["New York", "Mumbai", "Tokyo"];

### Maps

    // 映射是关联键和值的对象
    var person = Map<String, String>();
    // 要初始化地图，请执行以下操作：
    person['firstName'] = 'Nicola';
    person['lastName'] = 'Tesla';
    print(person);
    // 打印: {firstName:Nicola, lastName:Tesla}
    print(person['lastName']);
    // 打印: Tesla

    var nobleGases = {
      // Key: Value
      2: 'helium',
      10: 'neon',
      18: 'argon',
    };

### Sets

    // Dart 中的集合是唯一项的无序集合
    var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
    // 创建一个空集
    var names = <String>{};
    Set<String> names = {}; // 这也有效
    //var names = {}; // 创建地图，而不是集合

## 函数

### 函数示例

    // dart 中的函数是对象并且有一个类型
    int add(int a, int b){
        return a+b;
    }
    // 函数可以分配给变量
    int sum = add(2,3); // 回报：5
    // 可以作为参数传递给其他函数
    int totalSum = add(2, add(2,3)); // 返回：7

### 箭头语法 (=>)

    // 只包含一个表达式的函数，您可以使用简写语法
    bool isFav(Product product) => favProductsList.contains(product);

### Anonymous (lambda) functions

    // 没有名字的小单行函数
    int add(a,b) => a+b;
    // lambda 函数大多作为参数传递给其他函数
    const list = [
      'apples', 'bananas', 'oranges'
    ];

    list.forEach(
      (item) =>
        print('${list.indexOf(item)}: $item')
    );
    // 打印: 0: apples 1: bananas 2: oranges

## 类和对象

### 类 Class

    class Cat {
        String name;
        // 方法
        void voice(){
            print("Meow");
        }
    }

### 对象 Object

    // 类的实例
    // 在 myCat 下面是 Cat 类的对象
    void main(){
        Cat myCat = Cat();
        myCat.name = "Kitty";
        myCat.voice(); // 打印: Meow
    }

### 构造函数

    class Cat {
        String name;
        Cat(this.name);
    }
    void main(){
        Cat myCat = Cat("Kitty");
        print(myCat.name); // 打印: Kitty
    }

### 抽象类

    // 抽象类——不能实例化的类
    // 这个类被声明为抽象的，因此不能被实例化
    abstract class AbstractContainer {
      // 定义构造函数、字段、方法...
      void updateChildren(); // 抽象方法
    }

### Getters Setters

    // 提供对对象属性的读写访问
    class Cat {
        String name;
        // getter
        String get catName {
            return name;
        }
        // setter
        void set catName(String name){
            this.name = name;
        }
    }

## 隐式接口

### 一个基本的界面

    // 一个人。隐式接口包含 greet()。
    class Person {
      // 在接口中，但仅在此库中可见。
      final String _name;
      // 不在接口中，因为这是一个构造函数。
      Person(this._name);
      // 在接口中
      String greet(String who) => 'Hello, $who. I am $_name.';
    }
    // Person 接口的实现。
    class Impostor implements Person {
      String get _name => '';
      String greet(String who) => 'Hi $who. Do you know who I am?';
    }
    String greetBob(Person person) => person.greet('Bob');
    void main() {
      print(greetBob(Person('Kathy')));
      // 打印: Hello, Bob. I am Kathy.
      print(greetBob(Impostor()));
      // 打印: Hi Bob. Do you know who I am?
    }

### 扩展类

    class Phone {
        void use(){
            _call();
            _sendMessage();
        }
    }
    // 使用 extends 创建子类
    class SmartPhone extends Phone {
        void use(){
            // 使用 super 来引用超类
            super.use();
            _takePhotos();
            _playGames();
        }
    }

## 异常

### Throw

    // 抛出 throws 或引发 raises 和异常 exception
    throw IntegerDivisionByZeroException();
    // 你也可以抛出任意对象
    throw "Product out of stock!";

### Catch

    try {
        int c = 3/0;
        print(c);
    } on IntegerDivisionByZeroException {
        // 一个特定的异常
        print('Can not divide integer by 0.')
    } on Exception catch (e) {
        // 任何其他异常情况
        print('Unknown exception: $e');
    } catch (e) {
        // 没有指定类型，处理所有
        print('Something really unknown: $e');
    }

### Finally

    // 确保某些代码无论是否抛出异常都能运行
    try {
      cookFood();
    } catch (e) {
      print('Error: $e'); // 先处理异常
    } finally {
      cleanKitchen();     // 然后清理
    }

## Futures

### Async Await

    // 异步函数：它们在设置可能耗时的操作后返回
    // async 和 await 关键字支持异步编程
    Future<String> login() {
      String userName="Temidjoy";
      return
        Future.delayed(
          Duration(seconds: 4), () => userName
        );
    }
    // 异步
    main() async {
      print('Authenticating please wait...');
      print(await userName());
    }

## 各种各样的

### Null 和 Null 感知

    int x; // 任何对象的初始值为 null
    // ?? 空感知运算符
    x ??=6;   // ??= 赋值运算符，仅当变量当前为 null 时才为其赋值
    print(x); // 打印: 6
    x ??=3;
    print(x); // 打印: 6 - 结果仍然是 6
    print(null ?? 10); // 打印: 10。如果不为空，则显示左侧的值，否则返回右侧的值

### 三元运算符

    // 条件 ? 条件如果为真 : 条件如果为假
    bool isAvailable;
    isAvailable ? orderproduct() : addToFavourite();

### 条件属性访问

    userObject?.userName
    // 上面的代码片段等效于以下代码：
    (userObject != null) ? userObject.userName : null
    // 您可以将 ? 的多种用途链接起来。一起在一个表达式中
    userObject?.userName?.toString()
    // 如果 userObject 或 userObject.userName 为 null，则前面的代码返回 null 并且从不调用 toString()

### 级联符号 (..)

    // 允许您对同一对象进行一系列操作
    // 而不是这样做
    var user = User();
    user.name = "Nicola";
    user.email = "nicola@g.c";
    user.age = 24;
    // 你可以这样做
    var user = User()
      ..name = "Nicola"
      ..email = "nicola@g.c"
      ..age = 24;

### 扩展运算符 (...)

    // 将多个值插入到集合中
    var list = [1, 2, 3];
    var list2 = [0, ...list];
    print(list2.length); // 打印: 4

## 另见

- Dart 官方文档 (dart.dev)