Skip to content

Dart 类型系统与内置类型

1. 类型系统概览

Dart 是一种 类型安全(sound type system) 的语言。 类型安全保证了 变量的静态类型与运行时的值保持一致

  • 静态分析:在编译阶段检查类型错误。
  • 运行时检查:在必要时确保类型符合预期。
  • 类型推断:Dart 可以自动推断大部分变量和表达式的类型,无需显式标注。

2. 类型安全(Soundness)

类型安全意味着: 如果某个表达式的静态类型是 T,那么它的运行时值一定是 TT 的子类型。

优点:

  • 提前发现错误
  • 提高代码可靠性
  • IDE 支持更完善的代码提示和补全

3. 类型推断(Type Inference)

Dart 编译器会根据上下文自动推断类型:

dart
var name = 'Alice';   // 推断为 String
final numbers = [1, 2, 3];  // 推断为 List<int>

在泛型中也会自动推断:

dart
var list = <int>[];   // List<int>

如果无法推断,类型默认为 dynamic


4. Null 安全(Null Safety)

  • 默认情况下,所有类型都是 不可为 null
  • 如果某个变量可以为 null,需要显式标注 ?
dart
String name = 'Bob';     // 不可为 null
String? nickname = null; // 可为 null

运算符:

  • !:断言不为 null(可能抛异常)
  • ?.:空安全访问运算符
  • ??:提供默认值
  • ??=:仅当变量为 null 时赋值

5. 内置类型

Dart 所有类型都是 Object 的子类。以下为常见内置类型:

数字(Numbers)

  • int:整数,64 位
  • double:浮点数,64 位 IEEE 754
dart
int a = 10;
double b = 3.14;
num c = a + b; // num 是 int 和 double 的超类型

字符串(String)

  • UTF-16 编码
  • 支持插值(${}
dart
var name = 'Alice';
print('Hello $name');
print('Length: ${name.length}');

布尔值(bool)

dart
bool isLoggedIn = true;

列表(List)

  • 有序集合
  • 索引从 0 开始
dart
var list = <int>[1, 2, 3];
list.add(4);
print(list[0]); // 1

集合(Set)

  • 无序,不重复
dart
var set = <String>{'a', 'b', 'c'};
set.add('d');

映射(Map)

  • 键值对集合
  • 键可以是任意类型(通常是 String
dart
var map = <String, int>{'a': 1, 'b': 2};
map['c'] = 3;
print(map['a']); // 1

符号(Symbol)

用于反射,较少使用:

dart
Symbol s = #mySymbol;

Runes 与 Characters

用于处理 Unicode 字符:

dart
var heart = '\u2665'; // ♥

6. 动态类型与 dynamic

如果不确定类型,可以使用 dynamic

dart
dynamic x = 'hello';
x = 123; // 允许重新赋值为不同类型

但应尽量避免,推荐使用明确类型。


7. 泛型(Generics)

Dart 提供泛型来保证集合和方法的类型安全:

dart
List<String> names = ['Alice', 'Bob'];
Map<String, int> scores = {'Alice': 95, 'Bob': 88};

自定义泛型类:

dart
class Box<T> {
  T value;
  Box(this.value);
}

var intBox = Box<int>(123);

8. 类型检查运算符

  • is:是否为某类型
  • is!:是否不是某类型
  • as:类型转换
dart
if (x is String) {
  print(x.length);
}

var y = x as String;

9. 未来与可选类型(Future & Optional)

在异步编程中常用:

dart
Future<String> fetchUser() async {
  return 'Alice';
}