Built-in types

Built-in types

Dart 语言为以下类型提供了特殊支持:

  • 数字(int, double
  • 字符串(String
  • 布尔值(bool
  • 记录((value1, value2))
  • 函数(Function
  • 列表(List,也被称为数组)
  • 集合(Set
  • 映射(Map
  • Rune(Runes;通常被 characters API 替代)
  • Symbol(Symbol
  • null 值(Null

这种支持包括使用字面量创建对象的能力。例如,'this is a string' 是一个字符串字面量,而 true 是一个布尔字面量。

因为 Dart 中的每个变量都指向一个对象——即一个类的实例——所以你通常可以使用构造函数来初始化变量。一些内置类型有它们自己的构造函数。例如,你可以使用 Map() 构造函数来创建一个映射。

其他一些类型在 Dart 语言中也扮演着特殊的角色:

  • Object:除 Null 之外所有 Dart 类的超类。
  • Enum:所有枚举的超类。
  • FutureStream:用于异步编程。
  • Iterable:用于 for-in 循环和同步生成器函数。
  • Never:表示一个表达式永远无法成功完成求值。最常用于总是抛出异常的函数。
  • dynamic:表示你想要禁用静态检查。通常你应该使用 ObjectObject? 来替代。
  • void:表示一个值永远不会被使用。通常用作返回类型。

ObjectObject?NullNever 类在类继承体系中扮演着特殊的角色。请在 理解空安全 中了解这些角色的作用。

数字

Dart 的数字有两种类型:

int
不大于 64 位的整数值,具体取决于平台。在原生平台上,值的范围是 -263 到 263 - 1。在 Web 平台上,整数值被表示为 JavaScript 数字(没有小数部分的 64 位浮点数值),范围是 -253 到 253 - 1。
double
64 位(双精度)浮点数,遵循 IEEE 754 标准。
intdouble 都是 num 的子类型。num 类型包含了 +-/* 等基本运算符,你也可以在该类型中找到 abs()ceil()floor() 等方法。(位运算符,如 >>,则定义在 int 类中。)如果 num 及其子类型没有你想要的功能,可以看看 dart:math 库。

整数是没有小数点的数字。以下是一些定义整数字面量的示例:

1
2
var x = 1;
var hex = 0xDEADBEEF;

如果一个数字包含小数点,它就是 double 类型。以下是一些定义双精度浮点数字面量的示例:

1
2
var y = 1.1;
var exponents = 1.42e5;

你也可以将一个变量声明为 num 类型。如果这样做,该变量可以同时持有整数和双精度浮点数值。

1
2
num x = 1; // x 可以同时持有 int 和 double 值
x += 2.5;

在必要时,整数字面量会自动转换为双精度浮点数:

1
double z = 1; // 等价于 double z = 1.0。

以下是如何将字符串转换为数字,反之亦然:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// String -> int
var one = int.parse('1');
assert(one == 1);

// String -> double
var onePointOne = double.parse('1.1');
assert(onePointOne == 1.1);

// int -> String
String oneAsString = 1.toString();
assert(oneAsString == '1');

// double -> String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == '3.14');

int 类型支持传统的按位移位(<<, >>, >>>)、取反(~)、与(&)、或(|)以及异或(^)运算符,这些对于操作和屏蔽位域中的标志位非常有用。例如:

1
2
3
assert((3 << 1) == 6); // 0011 << 1 == 0110
assert((3 | 4) == 7); // 0011 | 0100 == 0111
assert((3 & 4) == 0); // 0011 & 0100 == 0000

更多示例,请参见位和移位运算符部分。

数字字面量是编译时常量。许多算术表达式也是编译时常量,只要它们的操作数是能求值为数字的编译时常量即可。

1
2
3
const msPerSecond = 1000;
const secondsUntilRetry = 5;
const msUntilRetry = secondsUntilRetry * msPerSecond;

更多信息,请参见 Dart 中的数字

你可以使用一个或多个下划线 (_)作为数字分隔符,以使较长的数字字面量更具可读性。多个数字分隔符允许更高层次的分组。

1
2
3
4
5
var n1 = 1_000_000;
var n2 = 0.000_000_000_01;
var n3 = 0x00_14_22_01_23_45; // MAC 地址
var n4 = 555_123_4567; // 美国电话号码
var n5 = 100__000_000__000_000; // 一百个百万的百万!

版本说明
使用数字分隔符需要语言版本至少为 3.6。

字符串

一个 Dart 字符串(String 对象)持有一系列的 UTF-16 码元。你可以使用单引号或双引号来创建一个字符串:

1
2
3
4
var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
var s3 = 'It\'s easy to escape the string delimiter.';
var s4 = "It's even easier to use the other delimiter.";

你可以使用 ${expression} 将表达式的值放入字符串中。如果表达式是一个标识符,你可以省略 {}。为了获取一个对象对应的字符串,Dart 会调用该对象的 toString() 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
var s = 'string interpolation';

assert(
'Dart has $s, which is very handy.' ==
'Dart has string interpolation, '
'which is very handy.',
);
assert(
'That deserves all caps. '
'${s.toUpperCase()} is very handy!' ==
'That deserves all caps. '
'STRING INTERPOLATION is very handy!',
);

注意
== 运算符测试两个对象是否相等。如果两个字符串包含相同的码元序列,那么它们就是相等的。

你可以使用相邻的字符串字面量或 + 运算符来连接字符串:

1
2
3
4
5
6
7
8
9
10
11
12
var s1 =
'String '
'concatenation'
" works even over line breaks.";
assert(
s1 ==
'String concatenation works even over '
'line breaks.',
);

var s2 = 'The + operator ' + 'works, as well.';
assert(s2 == 'The + operator works, as well.');

要创建多行字符串,请使用带有单引号或双引号的三重引号:

1
2
3
4
5
6
7
var s1 = '''
You can create
multi-line strings like this one.
''';

var s2 = """This is also a
multi-line string.""";

你可以通过在字符串前加上 r 来创建一个“原始”字符串:

1
var s = r'In a raw string, not even \n gets special treatment.';

有关如何在字符串中表示 Unicode 字符的详细信息,请参见 Rune 和字形簇

字符串字面量是编译时常量,只要任何插值表达式是求值为 null 或数字、字符串、布尔值的编译时常量即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
// 这些在 const 字符串中是有效的。
const aConstNum = 0;
const aConstBool = true;
const aConstString = 'a constant string';

// 这些在 const 字符串中是无效的。
var aNum = 0;
var aBool = true;
var aString = 'a string';
const aConstList = [1, 2, 3];

const validConstString = '$aConstNum $aConstBool $aConstString';
// const invalidConstString = '$aNum $aBool $aString $aConstList';

有关使用字符串的更多信息,请查阅字符串和正则表达式

布尔值

为了表示布尔值,Dart 有一个名为 bool 的类型。只有两个对象是 bool 类型:布尔字面量 truefalse,它们都是编译时常量。

Dart 的类型安全意味着你不能使用像 if (nonbooleanValue)assert (nonbooleanValue) 这样的代码。相反,你应该明确地检查值,像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 检查空字符串。
var fullName = '';
assert(fullName.isEmpty);

// 检查零。
var hitPoints = 0;
assert(hitPoints == 0);

// 检查 null。
var unicorn = null;
assert(unicorn == null);

// 检查 NaN。
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN);

Rune 和字形簇

在 Dart 中,Rune 用于公开字符串的 Unicode 码位。你可以使用 characters 包来查看或操作用户感知的字符,也称为 Unicode(扩展)字形簇。

Unicode 为世界上所有书写系统中使用的每个字母、数字和符号都定义了一个唯一的数值。因为 Dart 字符串是 UTF-16 码元的序列,所以在字符串中表示 Unicode 码位需要特殊的语法。表示一个 Unicode 码位的通常方式是 \uXXXX,其中 XXXX 是一个 4 位的十六进制值。例如,心形字符 (♥) 是 \u2665。要指定多于或少于 4 个十六进制数字,请将该值放在花括号中。例如,笑哭的表情符号 (😆) 是 \u{1f606}

如果你需要读取或写入单个 Unicode 字符,请使用由 characters 包在 String 上定义的 characters getter。返回的 Characters 对象是作为字形簇序列的字符串。以下是使用 characters API 的一个例子:

1
2
3
4
5
6
7
8
import 'package:characters/characters.dart';

void main() {
var hi = 'Hi 🇩🇰';
print(hi);
print('The end of the string: ${hi.substring(hi.length - 1)}');
print('The last character: ${hi.characters.last}');
}

根据你的环境,输出大致如下:

1
2
3
4
dart run bin/main.dart
Hi 🇩🇰
The end of the string: ???
The last character: 🇩🇰

有关使用 characters 包操作字符串的详细信息,请参阅 characters 包的示例和 API 参考

Symbol

一个 Symbol 对象表示 Dart 程序中声明的运算符或标识符。你可能永远不需要使用 Symbol,但对于按名称引用标识符的 API 来说,它们是无价的,因为代码压缩会改变标识符的名称,但不会改变标识符的 Symbol。

要获取一个标识符的 Symbol,请使用 Symbol 字面量,它就是 # 后面跟着标识符:

1
2
#radix
#bar

Symbol 字面量是编译时常量。

作者

wuhunyu

发布于

2025-09-03

更新于

2025-09-11

许可协议