关于Dart2那些事儿-内建类型

2019-12-06  本文已影响0人  WizardL

生活的道路一旦选定,就要勇敢地走到底,决不回头。——左拉

Dart语言对以下类型有特殊的支持:

您可以使用字面量初始化任何这些特殊类型的对象。例如,'this is a string'是字符串字面量,而true是一个布尔型字面量。

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

Numbers

Dart的数字有两种形式:

int

根据平台的不同,整数值不大于64位。在Dart VM上,值可以从-263到263 - 1。编译成JavaScript的Dart使用JavaScript代码,允许值从-253到253 - 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中反转字符串?

Symbols(符号)

译者注:这部分内容大家可以再后续章节中出现时结合了解就行,只看概念很难理解的。

符号对象表示在Dart程序中声明的操作符或标识符。您可能永远不需要使用符号,但是对于按名称引用标识符的api来说,它们是非常重要的,因为缩小改变了标识符名称而不是标识符符号。

要获取标识符的符号,请使用符号文字,符号文字仅为#,后面跟着标识符:

#radix
#bar

符号常量是编译时常量。

上一篇下一篇

猜你喜欢

热点阅读