# 基本语法

## 重要概念

* 一切皆对象（Object），数字、函数、null等
* 类型推断
* 支持泛型 &#x20;
* 支持顶层函数和顶层变量，和kotlin一样 &#x20;
* 没有public、protocted、private修饰符。如果以\_开头，代表对库可见 &#x20;
* Dart 2中构造方法new是可选的

## 变量

* 使用var声明的变量类型推断后，不能修改类型
* dynamic或Object声明的变量后面可以修改类型。（吊炸天）

## 默认值

没有初始化的变量的默认值都是null，哪怕你是number，**这点和很多语言都不一样哦**。

## Final和Const

如果一个变量永远不改变，那么可以使用final和const。final变量只能被设置一次，const变量是编译时常量，隐试final。

const不仅可以修饰变量，也可以修改值。（**这个和c++一样**）

## Map

```
var gifts = {
  // Key:    Value
  'first': 'partridge',
  'second': 'turtledoves',
  'fifth': 'golden rings'
};
```

## 函数

* \[]表示参数可选
* {}命名参数
* \=使用默认值，必须是编译时常量，否则null

## Exceptions

Dart中所有的异常都是非受检异常。

throw是个表达式，不仅可以抛异常，还能抛其他任意对象。

```
try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // A specific exception
  buyMoreLlamas();
} on Exception catch (e) {
  // Anything else that is an exception
  print('Unknown exception: $e');
} catch (e) {
  // No specified type, handles all
  print('Something really unknown: $e');
}
```

需要处理指定异常类型时使用on；使用catch处理Exception

catch可以指定多个参数，catch(e,s)，e代表Exception对象，e代表StackTrace对象

处理完异常，再抛出时使用rethrow关键字。

```dart
try {
  breedMoreLlamas();
} catch (e) {
  print('Error: $e'); // Handle the exception first.
} finally {
  cleanLlamaStalls(); // Then clean up.
}
```

## Classes

```dart
// If p is non-null, set its y value to 4.
p?.y = 4;
```

**?.**

### 调用构造方法

> Dart 2中new是可选的

在一个constant上下文中，const是可以省略的。

### 获取对象的类型

runtimeType参数，返回Type对象

### 实例变量

```dart
class Point {
  num x;
  num y;
}

void main() {
  var point = Point();
  point.x = 4; // Use the setter method for x.
  assert(point.x == 4); // Use the getter method for x.
  assert(point.y == null); // Values default to null.
}
```

实例变量生成getter方法，非final实例生成get和set方法。

### 构造方法

默认构造方法都是有的；

默认构造方法就是名称和类名一样的，剩下的就需要使用命名构造方法。

#### 命名构造方法

```dart
class Point {
  num x, y;

  Point(this.x, this.y);

  // Named constructor
  Point.origin() {
    x = 0;
    y = 0;
  }
}
```

#### 常构造方法

```dart
class ImmutablePoint {
  static final ImmutablePoint origin =
      const ImmutablePoint(0, 0);

  final num x, y;

  const ImmutablePoint(this.x, this.y);
}
```

实例变量需要是final的。

### 工厂构造器

当构造方法不是每次都创建实例时，可以使用factory关键字进行标记。

> factory构造器没有this访问符

### 抽象方法

```dart
abstract class Doer {
  // Define instance variables and methods...

  void doSomething(); // Define an abstract method.
}

class EffectiveDoer extends Doer {
  void doSomething() {
    // Provide an implementation, so the method is not abstract here...
  }
}
```

;代替方法体即可。

每个类有个隐试的接口，神奇吧？

### 重载运算符

Dart支持重载运算符

```dart
class Vector {
  final int x, y;

  Vector(this.x, this.y);

  Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
  Vector operator -(Vector v) => Vector(x - v.x, y - v.y);

  // Operator == and hashCode not shown. For details, see note below.
  // ···
}
```

如果重载了==，那么也要重载hashCode

### noSuchMethod()

Object有noSuchMethod()方法，子类可以重载该方法，当调用没有的属性或方法时将会调用该方法。

### 枚举类

```dart
enum Color{red,green,blue}

asset(Color.red.index==0)

List<Color> value=Color.values;
```

### 类变量和方法

static关键字

## 泛型

### 集合字面量

```dart
var names = <String>['Seth', 'Kathy', 'Lars'];
var pages = <String, String>{
  'index.html': 'Homepage',
  'robots.txt': 'Hints for web robots',
  'humans.txt': 'We are people, not machines'
};
```

### 泛型方法

```dart
T first<T>(List<T> ts) {
  // Do some initial work or error checking, then...
  T tmp = ts[0];
  // Do some additional checking or processing...
  return tmp;
}
```

## 异步支持

```dart
Future checkVersion() async {
  var version = await lookUpVersion();
  // Do something with version
}
```

为了使用await，代码必须要在一个async的函数中。

### 声明异步函数

```dart
Future<String> lookUpVersion() async => '1.0.0';
```

使用了async关键字，那么函数返回得是Future类型.

### 处理流

当需要从流中获取值时，有两种方法：\
1\. 使用async和一个异步的循环（await for） 2. 使用Stream API

```dart
await for (varOrType identifier in expression) {
  // Executes each time the stream emits a value.
}

Future main() async {
  // ...
  await for (var request in requestServer) {
    handleRequest(request);
  }
  // ...
}
```

### Generators

当你想生成一序列的值时：

* Synchronous Generator：返回Iterable对象 &#x20;
* Asynchronous Generator：返回Stream对象 &#x20;

```dart
Iterable<int> naturalsTo(int n) sync* {
  int k = 0;
  while (k < n) yield k++;
}
```

sync\*标记函数，yield声明发布值

```dart
Stream<int> asynchronousNaturalsTo(int n) async* {
  int k = 0;
  while (k < n) yield k++;
}
```

如果generator是递归的，那么可以使用yield\*进行优化。

```dart
Iterable<int> naturalsDownFrom(int n) sync* {
  if (n > 0) {
    yield n;
    yield* naturalsDownFrom(n - 1);
  }
}
```

## Callable类

为了让你的类可以像函数一样被调用，使用call()方法。

```dart
class WannabeFunction {
  call(String a, String b, String c) => '$a $b $c!';
}

main() {
  var wf = new WannabeFunction();
  var out = wf("Hi","there,","gang");
  print('$out');
}
```
