[TOC]
Dart語言對以下類型有特殊的支持:
* numbers
* strings
* booleans
* lists (also known as arrays)
* maps
* runes (for expressing Unicode characters in a string)
* symbols
您可以使用字面量初始化任何這些特殊類型的對象。例如,'this is a string'是字符串字面量,而true是一個布爾型字面量。
因為Dart中的每個變量都指向一個對象——類的實例——你通常可以使用構造函數來初始化變量。有些內置類型有自己的構造函數。例如,可以使用Map()構造函數創建映射。
## Numbers
Dart的數字有兩種形式:
### int
根據平臺的不同,整數值不大于64位。在Dart VM上,值可以從-2<sup>63</sup>到2<sup>63</sup> - 1。編譯成JavaScript的Dart使用JavaScript代碼,允許值從-2<sup>53</sup>到2<sup>53</sup> - 1。
### double
64位(雙精度)浮點數,由IEEE 754標準指定。
int和double都是num的子類型。num類型包括基本的操作符,如+、-、/和*,您還可以在其中找到abs()、ceil()和floor()等方法。(位運算符,如>>,在int類中定義。)如果num及其子類型沒有您要查找的內容,那么dart:math library可能會有。
整數是沒有小數點的數。這里有一些定義整數字面量的例子:
~~~
int x = 1;
int hex = 0xDEADBEEF;
~~~
如果一個數字包含一個小數,它就是一個雙精度數。這里有一些定義雙精字面量的例子:
~~~
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}將表達式的值放入字符串中。如果表達式是一個標識符,可以跳過{}。為了獲得與對象對應的字符串,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前綴創建一個“原始”字符串:
~~~
var s = r'In a raw string, not even \n gets special treatment.';
~~~
有關如何在字符串中表示Unicode字符的詳細信息,請參見[Runes]。
字符串字面量是編譯時常量,只要任何內插表達式都是編譯時常量,計算結果為null或數值、字符串或布爾值。
~~~
// 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';
~~~
有關使用字符串的更多信息,請參見[字符串和正則表達式]。
## Booleans
為了表示布爾值,Dart有一個名為bool的類型。只有兩個對象具有bool類型:布爾字面量true和false,它們都是編譯時常量。
Dart的類型安全性意味著您不能使用if(非booleanvalue)或assert(非booleanvalue)之類的代碼。相反,顯式地檢查值,如:
~~~
// 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);
~~~
## Lists
也許幾乎所有編程語言中最常見的集合就是數組或有序對象組。在Dart中,數組是列表對象,所以大多數人把它們叫做列表。
Dart列表字面量看起來像JavaScript數組字面量。這是一個簡單的Dart列表:
~~~
var list = [1, 2, 3];
~~~
>注意:分析器推斷該列表具有List\<int>類型。如果試圖向此列表添加非整型對象,則分析器或運行時將引發錯誤。有關更多信息,請閱讀[有關類型推斷的文章]。
>
列表使用基于0的索引,其中0是第一個元素和列表的索引。[長度- 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; // Uncommenting this causes an error.
~~~
列表類型有許多便于操作列表的方法。有關列表的更多信息,請參見[泛型] (Generics )和[集合] (Collections)。
## Maps
>譯者注:在很多地方將maps翻譯為映射,但是由于人們對于英語單詞的第一釋義并不是很好理解。所以在本文檔中我對maps沒有做翻譯,把他理解為一種數據類型就行。
>
通常,map是一個關聯鍵和值的對象。鍵和值都可以是任何類型的對象。每個鍵只出現一次,但是您可以多次使用相同的值。Dart對map的支持是通過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添加錯誤類型的值,則分析器或運行時將引發錯誤。更多內容參見[類型推斷]
>
您同樣可以使用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關鍵字是可選的。有關詳細信息參見[使用構造函數]
>
在現有的map中添加一個新的鍵值對,就像在JavaScript中那樣:
~~~
var gifts = {'first': 'partridge'};
gifts['fourth'] = 'calling birds'; // Add a key-value pair
~~~
從map中檢索值的方式與在JavaScript中一樣:
~~~
var gifts = {'first': 'partridge'};
assert(gifts['first'] == 'partridge');
~~~
如果你要獲取的鍵不再map中,將會返回一個null:
~~~
var gifts = {'first': 'partridge'};
assert(gifts['fifth'] == null);
~~~
使用.length獲取map中元素的個數:
~~~
var gifts = {'first': 'partridge'};
gifts['fourth'] = 'calling birds';
assert(gifts.length == 2);
~~~
要創建一個編譯時常量的map需要在map的字面量前加const關鍵字:
~~~
final constantMap = const {
2: 'helium',
10: 'neon',
18: 'argon',
};
// constantMap[2] = 'Helium'; // Uncommenting this causes an error.
~~~
更多關于maps的知識參見[泛型和maps]
## Runes(字符)
在Dart中,字符是字符串的UTF-32編碼點。
Unicode為世界上所有的書寫系統中使用的每個字母、數字和符號定義一個唯一的數值。因為Dart字符串是UTF-16代碼單元的序列,所以在字符串中表示32位的Unicode值需要特殊的語法。
表示Unicode碼點的常用方法是\uXXXX,其中XXXX是4位數的十六進制值。例如,心型字符(?)的編碼為\ u2665。要指定大于或小于4位十六進制數字,請將值放在花括號中。例如笑臉表情(??)的編碼\u{1f600}.
String類有幾個屬性可以用來獲取runes信息。codeUnitAt和codeUnit屬性返回16位代碼單元。使用字符屬性獲取字符串的字符。
下面的示例說明了字符、16位代碼單元和32位代碼點之間的關系。
~~~
main() {
var clapping = '\u{1f600}';
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));
}
//運行效果如下
??
[55357, 56832]
[128512]
? ?? ?? ?? ?? ??
Process finished with exit code 0
~~~
注意:使用列表操作操作runes時要小心。根據特定的語言、字符集和操作,這種方法很容易出錯。有關更多信息,請參見[如何在Dart中反轉字符串?](https://stackoverflow.com/questions/21521729/how-do-i-reverse-a-string-in-dart)
## Symbols(符號)
>譯者注:這部分內容大家可以再后續章節中出現時結合了解就行,只看概念很難理解的。
符號對象表示在Dart程序中聲明的操作符或標識符。您可能永遠不需要使用符號,但是對于按名稱引用標識符的api來說,它們是非常重要的,因為縮小改變了標識符名稱而不是標識符符號。
要獲取標識符的符號,請使用符號文字,符號文字僅為#,后面跟著標識符:
~~~
#radix
#bar
~~~
符號常量是編譯時常量。