如果你对 Dart 语言一无所知,推荐你先翻阅一些概念性解释,请访问 这篇文章。 如果你没有 Dart 环境,请使用在线编辑器,传送门。
Dart 支持以下数据类型:
- 数字(number)
- 字符串(string)
- 布尔值(boolean)
- 列表(list)
- 集合(set)
- 映射(map)
- 符文(rune)
- 符号(Symbol)
Dart 中数字类型用于表示数字文字,Dart 中的数字类型分为整数和双精度数两种,整数值不大于64位, 具体取决于平台。
你可以使用 int / double 关键字来显式声明一个整型 / 双精度变量:
int a = 10;
int b = 0xDEADBEEF;
double c = 3.14;
double d = 1.42e5;
另外,Dart 支持自动推断数据类型,所以你也可以像JS一样使用 var 关键字来声明:
var a = 88;
var b = 5.65;
字符串(String)
Dart 字符串是一组 UTF-16 单元序列,用于存储一些姓名地址等信息,并用双引号或单引号包裹。
你可以使用 String 关键字来显式声明一个字符串类型的变量:
String str1 = 'hello';
String str2 = "hello";
同样,你也可以让 Dart 自动推断类型:
var str = 'hello world!';
Dart 允许你使用 + 号进行字符串的拼接:
String str = 'hello ' + 'world!';
print(str); //hello world!
Dart 允许你使用连续三个单引号或者三个双引号实现多行字符串(保留缩进格式):
String str = '''
格式会保留,
你看。
''';
print(str);
// 格式会保留,
// 你看。
当然,最简洁的写法是通过 ${expression} 方式内嵌表达式,就像ES6的字符串模板语法:
String str = 'null';
String newStr = '这是${str}';
print(newStr); //这是null
布尔值(boolean)
Dart 只有字面量 true / false 是布尔类型,这两个对象都是编译时常量。
你可以使用 bool 关键字定义一个布尔值变量:
bool a = true;
bool b = false;
同样,你也可以让 Dart 自动推断类型:
var c = true;
列表(list)
其实 list 就是编程语言中常见的数据类型 Array(数组),但在 Dart 中用 List 对象表示数组。
你可以使用 list 关键字定义一个列表:
List arr = [1,2,3];
你也可以使用构造函数定义一个列表:
var ls = new List();
print(ls);//[]
构造函数创建的 List 对象同样可以指明类型,一旦指明则无法添加其他类型数据:
var ls = new List();
// 取消注释则会报错
// ls.add(1);
但要注意,一旦声明了 int 类型,你就无法添加其他类型的值:
// "4" String
List arr = [1,2,3,"4"];
// Error: Compilation failed.
Dart 中的 List 字面量非常像 JavaScript 中的 array 字面量,所以你尽可能让 Dart 自动推断类型:
var arr = [1,2,3];
注意,Dart 推断 arr 的类型为 List 。 如果尝试将非整数对象添加到此 List 中,则分析器或运行时会引发错误,就像上面所述(Error: Compilation failed.)。
如果你想定义 List 类型的编译时常量,那么你需要在 List 字面量之前添加 const 关键字:
// create list
var arr = const ["常量", "不可再运行时更改"];
最后,数组的访问与 JavaScript 非常相似:
var arr = const ["我是0", "我是1"];
print(arr[0]);//我是0
集合(Set)
顾名思义,其实就是一组同类型数据的集合。在 Dart 中 Set 是一个元素唯一且无需的集合。 Dart 为 Set 提供了 Set 字面量和 Set 类型。
版本提示: 虽然 Set 类型 一直是 Dart 的核心部分, 但在 Dart2.2 中才引入了 Set 字面量 。
你可以使用 set 关键字来定义一个集合:
Set cls = {"小王", "小杨"};
但要注意,一旦声明了 String 类型,你就无法添加其他类型的值:
Set cls = {"小王", "小杨", true};
// Error: Compilation failed.
采用字面量方式创建,即 var 关键字:
var cls = {true,false};
注意,Dart 推断 cls 的类型为 Set 。 如果尝试将非布尔对象添加到此 Set 中,则分析器或运行时会引发错误,就像上面所述(Error: Compilation failed.)。
如果你想定义 Set 类型的编译时常量,那么你需要在 Set 字面量之前添加 const 关键字:
final b = const {
"one",
"tow"
};
// 尝试运行时添加
b.add("three");// Cannot change unmodifiable set
要创建一个空集,使用前面带有类型参数的 {} ,或者将 {} 赋值给 Set 类型的变量:
Set a = {};
var b = {};
// test
print(a);//{}
print(b);//{}
注意,初学者可能很容易和下面要介绍的 Map ,也就是 Object(对象)混淆,这两者语法非常相似, 因为先有的 Map 字母量语法,所以 {} 默认是 Map 类型。
这样写,就是创建的空 Map 对象而不是 Set 对象,请注意语法上的细节:
var obj = {};
print(obj.runtimeType.toString());//JsLinkedHashMap
// Map
映射(Map)
不严格地说,你可以把它看作为 Object / JSON 。 Map 是用来关联 keys 和 values 的对象。 keys 和 values 可以是任何类型的对象。在一个 Map 对象中一个 key 只能出现一次。 但是 value 可以出现多次。
你可以使用 var 创建一个 Map 对象,这和 JavaScript 非常相似:
var person = {
// Key: Value
'name': '杨莹',
'age': '18',
'eat': 'true'
};
var nobleGases = {
// Key: Value
2: 'react',
10: 'vue',
18: 'spring boot'
};
print(person);// {name: 杨莹, age: 18, eat: true}
print(nobleGases);// {2: helium, 10: neon, 18: argon}
请注意,Dart 会将 person 的类型推断为 Map,nobleGases 的类型推断为 Map 。 如果你尝试在上面的 map 中添加错误类型,那么分析器或者运行时会引发错误。
当然,通过 Map 构造函数创建也是不错的选择:
var obj = Map();
obj['name'] = '杨莹';
obj['age'] = 18;
print(obj);// {name: 杨莹, age: 18}
请注意,这里为什么只有 Map() ,而不是使用 new Map()。在 Dart 2 中,new 关键字是可选的,具体可以参考 构造函数的使用。
获取到 key-value 可以通过以下语法获得:
var person = {
'name': '杨莹',
'age': 18
};
print(person['name']); //杨莹
print(person['age']); //18
使用 .length 函数获取当前 Map 中的 key-value 对数量:
var obj = new Map();
obj['flag'] = true;
print(obj.length);//1
如果 Map 中不包含所要查找的 key,那么 Map 返回 null:
var obj = {'name':'杨莹'};
assert(obj['age'] == null);//null
从上面所有类型可得知,Dart 可以创建运行时常量和编译时常量,那么 Map 也不例外:
final constantMap = const {
1: 'one',
2: 'two'
};
// constantMap[3] = 'three';
此时你若再程序运行时动态改变(取消上面的注释) constantMap 则会报错。
符文(Rune)由于该类型并不常用,甚至用不到,这篇不再贴代码只给出概念赘述 Rune。
在 Dart 中, Rune 用来表示字符串中的 UTF-32 编码字符。
Unicode 定义了一个全球的书写系统编码, 系统中使用的所有字母,数字和符号都对应唯一的数值编码。 由于 Dart 字符串是一系列 UTF-16 编码单元, 因此要在字符串中表示32位 Unicode 值需要特殊语法支持。
表示 Unicode 编码的常用方法是, \uXXXX, 这里 XXXX 是一个4位的16进制数。 例如,心形符号 (♥) 是 \u2665。 对于特殊的非 4 个数值的情况, 把编码值放到大括号中即可。 例如,emoji 的笑脸 (�) 是 \u{1f600}。
谨慎使用 list 方式操作 Rune 。 这种方法很容易引发崩溃, 具体原因取决于特定的语言,字符集和操作。
符号(Symbol)由于该类型并不常用,甚至用不到,这篇不再贴代码只给出概念赘述 Symbol。
一个 Symbol 对象表示 Dart 程序中声明的运算符或者标识符。 你也许永远都不需要使用 Symbol ,但要按名称引用标识符的 API 时, Symbol 就非常有用了。 因为代码压缩后会改变标识符的名称,但不会改变标识符的符号。 通过字面量 Symbol ,也就是标识符前面添加一个 # 号,来获取标识符的 Symbol 。
就像 #bar ,但要注意 Symbol 字面量是编译时常量。