内置类型
Dart语言特别支持以下类型:
- 数字
- 字符串
- 布尔型
- 列表(也称为数组)
- 映射表
- runes (用于表示Unicode字符串)
- symbols
使用一个字面初始化这些特殊的类型对象。例如,'this is a string'
是一个字符串,而true
是一个boolean字。 由于Dart的每个变量都是一个class实例对象的引用,故可使用构造函数初始化变量。一些内置类型拥有构造函数,比如可以使用Map()
构造函数创建一个map.
数字
Dart有两种数字类型:
int
依赖于平台,整型值不大于64位。在Dart VM,其值是-2<sup>63</sup>到2<sup>63</sup>-1。Dart编译到JavaScript使用的JavaScript numbers,允许值为-2<sup>53</sup>到2<sup>53</sup>-1。
double
64位(双精度)浮点数,按照IEEE 754标准。 int
和doble
都是num的子类。 num类型包含基本的+、-、/和*操作符,而且还具有abs()、ceil()和floor(),其他方法(位操作符,如>>定义在int
类)除外。如果 num 及其子类型没有您要的功能,dart:math可能有。 整数是没有小数的数字。下面是定义整数的例子:
int x = 1;
int hex = 0xDEADBEEF;
如果一个数字包含小数,它是一个double。下面是定义double的例子:
double y = 1.1;
double exponents = 1.42e5;
下面示例展示字符串数字之间如何互相转换:
// 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类型有典型的位移(<<,>>),与(&)和或(|)操作符。例如:
assert((3 << 1) == 6); // 0011 << 1 == 0110
assert((3 >> 1) == 1); // 0011 >> 1 == 0001
assert((3 | 4) == 7); // 0011 | 0100 == 0111
数字是编译期常量。一些数学表达式也是编译期常量。只要它们是计算值是数字,在编译期常量等价于数字。
const msPerSecond = 1000;
const secondsUntilRetry = 5;
const msUntilRetry = secondsUntilRetry * msPerSecond;
字符串
Dart字符串是UTF-16编码串。可以使用单、双引号创建字符串:
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}
将expression的值放入字符串。如果expression是一个标识符可忽略{}。Dart通过调用对象的toString()方法获取相应的字符串值。
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!');
注意:==操作符检测两个对象是否相等。如果两个字符串的编码串相同则它们是等价的。
连接字符串使用相邻字符串或者+
操作符:
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.');
相邻两个字符串是连接操作很容易导致误操作错而且也不易阅读
另一种方式创建多行字符串:使用三重单、双引号:
var s1 = '''
You can create
multi-line strings like this one.
''';
var s2 = """This is also a
multi-line string.""";
使用r
前缀创建"raw"字符串:
var s = r'In a raw string, not even \n gets special treatment.';
关于字符串成表示Unicode字符的详细信息查阅Runs。 字符串字面是编译期常量,只要任何插值确定为null、数字、字符串或boolean值在编译期都是常量。
// These work in a const string.
const aConstNum = 0;
const aConstBool = true;
const aConstString = 'a constant string';
// These do NOT work in a const string.
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';
有关使用字符串的详细信息,查阅Strings and regular expressions。
布尔型
为了表示布尔值, Dart有名为bool的类型。bool类型只有两个对象:true
和false
,均是编译期常量。 Dart类型安全意味着不能使用诸如if (非布尔值)
或assert (非布尔值)
。而是显式检查值,比如:
// Check for an empty string.
var fullName = '';
assert(fullName.isEmpty);
// Check for zero.
var hitPoints = 0;
assert(hitPoints <= 0);
// Check for null.
var unicorn;
assert(unicorn == null);
// Check for NaN.
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN);
列表
几乎在所有编程语言中数组或有序对象可能是最常见的集合。在Dart中数组是List对象,所以多数人叫它们为列表。Dart列表看起来像JavaScript数组。下面是Dart列表示例:
var list = [1, 2, 3];
注意:分析器推断出list的类型为
List<int>
。如果添加非整数到list对象,分析器或者运行时将引发错误。更多信息阅读type inference。
列表使用零基址索引,0是第一个元素的索引而list.length - 1
是最后一个元素的索引。可以像在JavaScript中一样获取列表长度和引用列表元素:
var list = [1, 2, 3];
assert(list.length == 3);
assert(list[1] == 2);
list[1] = 1;
assert(list[1] == 1);
在列表前添加const
字创建编译期列表常量:
var constantList = const [1, 2, 3];
// constantList[1] = 1; // 取消注释这里引发错误.
列表类型有许多方便的操作列表的方法。更多关于列表的信息,查阅Generics和Collections。
映射表
总的来说,map是将一组key和value关联在一起的对象。key和value可以是任意类型对象。每个key只允许唯一,但可以多次使用相同的value。Dart通过map字和Map类型提供映射表支持。 下面一对Dart map示例,创建和使用map:
var gifts = {
// Key: Value
'first': 'partridge',
'second': 'turtledoves',
'fifth': 'golden rings'
};
var nobleGases = {
2: 'helium',
10: 'neon',
18: 'argon',
};
分析器推断出
gifts
的类型是Map<String, String>
,nobleGases
类型为Map<int, String>
。如果添加错误类型的值到这两个map,分析器或者在运行时将引发错误。更多信息阅读type inference。
可以使用Map的构造函数创建相同的对象:
var gifts = Map();
gifts['first'] = 'partridge';
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings';
var nobleGases = Map();
nobleGases[2] = 'helium';
nobleGases[10] = 'neon';
nobleGases[18] = 'argon';
注意:您可能期望看到
new Map
而不是只有Map()
。从Dart2起,关键字new是可选的。更多详情查阅Using constructors。
添加新key-value到map跟JavaScript中一样:
var gifts = {'first': 'partridge'};
gifts['fourth'] = 'calling birds'; // Add a key-value pair
map检索value的方式和JavaScript相同:
var gifts = {'first': 'partridge'};
assert(gifts['first'] == 'partridge');
如果查找的key在map中不具有将返回null:
var gifts = {'first': 'partridge'};
assert(gifts['fifth'] == null);
使用.length
获取map中key-value数量:
var gifts = {'first': 'partridge'};
gifts['fourth'] = 'calling birds';
assert(gifts.length == 2);
添加const
在map字符前面创建编译期map常量:
final constantMap = const {
2: 'helium',
10: 'neon',
18: 'argon',
};
// constantMap[2] = 'Helium'; // 取消注释这里将触发错误
Runs
在Dart中,runes是UTF-32编码的字符串。 Unicode为每个字母、数字、符号定义唯一的数值,应用在世上所有书写系统中。由于Dart的字符串是UTF-16编码串,表达32位Unicode字符串不需要使用特殊的语法。 常用的方式表示Unicode编码是\uXXXX
。其中XXXX是16进制的4个数字值。比如,心符号(♥)是\u2665
。如果要指定多于或少于4个16进制数字,将值放在花括号内。比如微笑表情()是\u{1f600}
。 String里有几个属性用于提取rune信息。codeUnitAt
和codeUnit
属性返回16位编码单元。使用runes
属性返回字符串的runes。 下面的示例解释runes、16位编码和32位编码之间的关系。单击 "运行" 按钮观察runes。
main() {
var clapping = '\u{1f44f}';
print(clapping);
print(clapping.codeUnits);
print(clapping.runes.toList());
Runes input = new Runes(
'\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print(new String.fromCharCodes(input));
}
//运行结果by obaniu
[55357, 56399]
[128079]
♥
注意:使用list操作runes要小心。受具体的语言、字符集和操作影响这种方式很容易导致断裂。更多信息查阅Stack Overflow上的How do I reverse a String in Dart?。
Symbols
Symbols对象表示Dart程序中声明的操作符或标识符。可能永远都不用不到符号,但它们对于按名称引用标识符的API非常有用的。因为缩短更改标识符名, 没有更改标识符符号。
原文很拗口:because minification changes identifier names but not identifier symbols.
使用symbol字符获取标识符的symbol,它只是#
跟随标识符。
#radix
#bar
Symbol字符是编译器常量。