header-bg.jpg
Dart 基本概念之数据类型
发表于 2019-07-05 12:23
|
分类于 Dart
|
评论次数 0
|
阅读次数 227

Dart 内置支持的类型有 8 种:numStringboolList(其他语言一般称作 Array)、SetMapRunes(用于在字符串中表示 Unicode 字符)、Symbol

和其他编程语言一样,我们可以直接使用字面量来初始化这些类型,例如 'this is a string' 代表一个字符串字面量,true 代表布尔值字面量等等,接下来本文将对这些数据类型知识进行全面的归纳总结。

num(数值)

Dart 支持两种类型的数值:

我们可以使用 num 关键字声明一个 num 类型的变量,也可以选择 intdouble 关键字来声明,例如:

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 中的布尔值有两个字面量:truefalse

在 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) {
       ^
*/

! 取反操作符也只能用于 truefalse,否则也将报错:

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]
}

上面的代码中,初始化了一个长度为 2List,并且包含两个值为 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

发布评论
还没有评论,快来抢沙发吧!