Dart语言关键点

8,963 阅读4分钟

1 Dart保存在变量中的都是对象,并且所有对象都是对应一个 的实例(也即是说 都有一个类类型),无论数字 函数 或者null都是对象,都继承自 Object 类。

2 Dart强类型也支持类型推断,所以写的时候可以不用指定类型(依靠类型推断)

3 Dart支持顶级函数,有类函数和对象函数(静态函数和实例函数),还支持局部函数

4 dart 用 _ 表示私有函数

5 Dart 语法中包含 表达式( expressions ) (有运行时值)和 语句( statements ) (没有运行时值)。 例如,条件表达式 condition ? expr1 : expr2 的值可能是 expr1 或 expr2 。 将其与 if-else 语句 相比较,if-else 语句没有值。 一条语句通常包含一个或多个表达式,相反表达式不能直接包含语句。

5 const关键字 声明编译时常量: 这意味着变量的值在编译时就已经确定,并且在程序运行期间不可更改 变量声明的左侧: 此时它要求变量在声明时就必须赋值,并且赋值必须是编译时常量。例如,数值、字符串、其他的const变量或者某些表达式 变量声明的右侧: 此时它修饰的是值,表示该值在编译时就已经确定,并且整个对象是不可变的 修饰的集合或对象: 要求集合的元素必须是递归的编译时常数。 修饰的类的构造函数: 要求该类的所有成员都必须是final的

final 关键字 声明不可变的变量: 并不要求变量的值在编译时就已知 赋值时机: 可以在声明时赋值,也可以在构造函数中赋值 初始化: 第一次使用时初始化,如果是在声明时赋值,那么赋值可以是任意的,不一定是编译时常量 修饰的对象: 内部的可变成员仍然可以被修改,除非这些成员也被声明为final

总结: const比final更严格 要求变量的值在编译时就已经确定,并且在运行时不可变 而final只要求变量在初始化后不可变,但初始化时的值不必在编译时已知;
如果需要在编译时就固定变量的值,可以使用 const 类型变量。 如果 Const 变量是类级别的,需要标记为 static const。 在这些地方可以使用在编译时就已经固定不变的值,字面量的数字和字符串, 固定的变量,或者是用于计算的固定数字: ————————————————

6 dart 级联运算符
级联运算符 ( .. **)可以实现对同一个对像进行一系列的操作。除了调用函数,还可以访问同一对象上的字段属性。这通常可以节省创建临时变量的步骤,同时编写出更流畅的代码。 在返回对象的函数中谨慎使用级联操作符。 例如,下面的代码是错误的:

var sb = StringBuffer();
sb.write('foo')
  ..write('bar'); // Error: 'void' 没哟定义 'write' 函数。

7 dart 命名构造函数
在Dart中,命名构造函数是类的特殊类型的构造函数,它们可以用于创建类的新实例。在Dart中,命名构造函数是通过将构造函数声明为类的成员并为其指定名称来实现的。
以下是如何在Dart中创建和使用命名构造函数的示例:

class Person {
  String name;
  int age;
 
  // 默认构造函数
  Person(this.name, this.age);
 
  // 命名构造函数
  Person.fromJson(Map<String, dynamic> json) {
    name = json['name'];
    age = json['age'];
  }
}
 
void main() {
  // 使用默认构造函数
  var person1 = Person('Alice', 30);
 
  // 使用命名构造函数
  var person2 = Person.fromJson({'name': 'Bob', 'age': 25});
 
  print('${person1.name} is ${person1.age} years old.');
  print('${person2.name} is ${person2.age} years old.');
}

在上面的代码中,我们定义了一个名为Person的类,它有两个成员变量nameage。除了默认构造函数之外,我们还定义了一个命名构造函数fromJson,它接受一个JSON对象并从中初始化Person对象的成员。在main函数中,我们演示了如何使用这两种构造函数来创建Person对象。

[库和可见性](https://www.dartcn.com/guides/language/language-tour#%E5%BA%93%E5%92%8C%E5%8F%AF%E8%A7%81%E6%80%A7)

8 工厂构造函数

当执行构造函数并不总是创建这个类的一个新实例时,则使用 factory 关键字。 例如,一个工厂构造函数可能会返回一个 cache 中的实例, 或者可能返回一个子类的实例。

以下示例演示了从缓存中返回对象的工厂构造函数:

class Logger {
  final String name;
  bool mute = false;

  // 从命名的 _ 可以知,
  // _cache 是私有属性。
  static final Map<String, Logger> _cache =
      <String, Logger>{};

  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final logger = Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) print(msg);
  }
}

提示:  工厂构造函数无法访问 this。

9 如果要重写 == 操作符,需要重写对象的 hashCode getter 方法。 重写 == 和 hashCode 的实例,参考 Implementing map keys.