Dart 内置支持的类型有 8 种:num
、String
、bool
、List
(其他语言一般称作 Array
)、Set
、Map
、Runes
(用于在字符串中表示 Unicode 字符)、Symbol
。
和其他编程语言一样,我们可以直接使用字面量来初始化这些类型,例如 'this is a string'
代表一个字符串字面量,true
代表布尔值字面量等等,接下来本文将对这些数据类型知识进行全面的归纳总结。
num(数值)
Dart 支持两种类型的数值:
-
int
:整数值,其取值通常位于 -2^53 和 2^53 之间。 -
double
:64-bit(双精度)浮点数,符合IEEE 754
标准。
我们可以使用 num
关键字声明一个 num
类型的变量,也可以选择 int
或 double
关键字来声明,例如:
void main() {
num age = 1;
int width = 2;
double height = 3.14;
print(age is num);// output: true
print(age is int);// output: true
print(age is double);// output: false
print(width is num);// output: true
print(width is int);// output: true
print(width is double);// output: false
print(height is num);// output: true
print(height is int);// output: false
print(height is double);// output: false
}
String(字符串)
Dart 字符串是 UTF-16 编码的字符序列,可以使用单引号、双引号和三引号来创建字符串。
使用单引号来表示字符串时,字符串中的单引号需要使用 \
进行转译,除此之外,和使用双引号没有任何区别,而三引号相当于 JavaScript 中的反引号,可以表示多行字符串,用法如下:
void main() {
const css = '''
body {
margin: 0;
padding: 0;
}
''';
print(css);
}
/*
output:
body {
margin: 0;
padding: 0;
}
*/
如果需要在字符串中解析变量或表达式,用法为 ${expression}
,这也和 JavaScript 的反引号用法一模一样,不过不同的是,Dart 中单引号和双引号都能解析变量或表达式,并且如果只解析变量,则可以省略花括号,使用 $expression
即可,用法如下:
void main() {
const foo = 666;
const bar = 777;
const str = '$foo is a number';
const total = "total is ${foo + bar}";
print(str);// output: 666 is a number
print(total);// output: total is 1443
}
可以使用 +
操作符来把多个字符串连接为一个,也可以把多个字符串放到一起来实现同样的功能,在字符串前加上r
标识符,将输出原样字符,不会解析字符串中的转译符 \
,用法如下:
void main() {
const foo = 'String ' 'concatenation'
" works even over line breaks.";
print(foo);// output: String concatenation works even over line breaks.
const bar = 'The + operator '
+ 'works, as well.';
print(bar);// output: The + operator works, as well.
const str = r"In a raw string, even \n isn't special.";
print(str);// output: In a raw string, even \n isn't special.
}
Runes
在 Dart 中,Runes
代表字符串的 UTF-32 code points
,它继承自 Iterable
,所以它是一个由 int 元素
组成的可遍历的集合,每个字符串都有一个runes
属性,我们可以访问此属性以获取字符串的 UTF-32 code points
值,例如:
void main() {
final str = 'str'.runes;
print(str);// output: (115, 116, 114)
}
Dart 和 Java 一样,每个字符都是 UTF-16 编码,字符串就是 UTF-16 code units 字符序列
,UTF-16 编码的最大值是 2 的 16 次方,也就是 65536。如果某字符的 code point 大于 65536,就需要用组合来表示它的 code point,比如 😳
对应的 code point 是 [55357, 56883]
,在 Dart 中可以使用 .codeUnits
来获取字符的 code point,用法如下:
void main() {
const face = '😳';
print(face.codeUnits);// output: [55357, 56883]
print(face.runes);// output: (128563)
}
这种 unicode 字符也可以使用 \uXXXX
的格式来表示,作用是一模一样的,这里的 XXXX
是 4 个 16 进制的数,例如 ❤
对应的 code 是 \u2764
。对于非 4 个数值的情况, 把编码值放到大括号中即可,例如 👴
对应的 code 是 \u{1F474}
:
void main() {
const grandpa = '👴';
const grandpaCode = '\u{1F474}';
const heart = '❤';
const heartCode = '\u2764';
print(grandpa == grandpaCode);// output: true
print(heart == heartCode);// output: true
}
bool(布尔值)
Boolean 类型是所有编程语言中使用的最多的一种类型,和其他语言一样,Dart 中的布尔值有两个字面量:true
和 false
。
在 Dart 中可以使用关键字 bool
来初始化一个布尔值类型的变量,和 JavaScript 以及 PHP 这种弱类型语言不同,在 Dart 中只有 true
才会被认为是 true
,其他值都是 false
,并且 if 语句中的条件必须是 bool 类型的值或者变量,否则将会在调试环境下报错:
void main() {
const isTrue = 1;
if (!isTrue) {
print('is true');
}
}
/*
Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
Try changing the type of the left hand side, or casting the right hand side to 'bool'.
if (!isTrue) {
^
*/
!
取反操作符也只能用于 true
和 false
,否则也将报错:
void main() {
const isTrue = 1;
print(!isTrue);
}
/*
output:
Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
Try changing the type of the left hand side, or casting the right hand side to 'bool'.
print(!isTrue);
^
*/
List(列表、数组)
Dart 中的 List 在其他语言中一般称作 Array(数组),我们可以选择实例化 List
构造函数来获得一个 List
类型的变量,构造函数接受 1 个可选参数,这个参数代表 List
的长度,例如:
void main() {
final arr2 = List(2);
print(arr2);// output: [null, null]
}
上面的代码中,初始化了一个长度为 2
的 List
,并且包含两个值为 null
的成员。
除了实例化构造函数,我们还可以选择和 JavaScript、PHP 一样使用 []
字面量的形式来声明数组,并且可以用 .length
来获取数组的长度,例如:
void main() {
const arr = [555, 666, 888];
print(arr.length);// output: 3
}
也可以使用泛型的方式来声明一个 List
类型的变量,泛型的详细使用可以查看 Dart 泛型
void main() {
List<String> fruits = ['banana', 'cucumber'];
fruits.add( 'eggplant');
print(fruits[2]);// output: eggplant
}
操作 List
类型的 api 也有非常多,我就不再赘述,详细使用可以参考 List class 文档
Set(无序集合)
Dart 的 Set
类型和 Redis 的 Set
类型很相似,它表示无序集合,集合成员是唯一的,这就意味着集合中不能出现重复的数据。
声明一个 Set
类型的变量,可以选择实例化构造函数,例如:
void main() {
final data = Set();
data.add(1);
data.add(2);
data.add(2);
data.add('foo');
print(data);// output: {1, 2, foo}
}
和 List
一样,我们也可以选择字面量的形式来声明 Set
,例如:
void main() {
final numbers = {1, 2, 2, 3};
print(numbers);// output: {1, 2, 3}
}
Map
Dart 中的 Maps
和 PHP 中的关联数组
、JavaScript 中的 Object
很相似,即 key-value 形式的集合。键和值可以是任何类型的对象,每个键只出现一次, 而一个值则可以出现多次。Dart 通过 map 字面量 和 Map 类型支持 map,用法如下:
void main() {
const fruits = {1: 'banana', 2: 'cucumber', 'three': 'eggplant'};
print(fruits['three']);// output: eggplant
}
同样的,我们也可以使用 Map
构造函数初始化一个变量:
void main() {
final fruits = Map();
fruits[1] = 'banana';
fruits[2] = 'cucumber';
fruits[3] = 'eggplant';
print(fruits);// output: {1: banana, 2: cucumber, 3: eggplant}
}
和 List
一样,也可以使用泛类型来声明 Map
变量:
void main() {
Map<int, String> fruits = {
1: 'banana',
2: 'cucumber',
3: 'eggplant'
};
print(fruits[3]);// output: eggplant
}
Symbol
一个 Symbol object 代表 Dart 程序中声明的操作符或者标识符,可以使用 #
作为标识符的前缀,用法如下:
void main() {
var className = #Person;
print(className);// output: Symbol("Person")
Symbol className2 = #Person2;
print(className2);// output: Symbol("Person2")
}
Dart 的 Symbol
和 JavaScript 中的 Symbol
类似,需要用的地方很少,关于更多详情可以参考 dart:mirrors - reflection
