Dart 数据类型,看这篇就够了!

前言

如果你对 Dart 语言一无所知,推荐你先翻阅一些概念性解释,请访问 这篇文章
如果你没有 Dart 环境,请使用在线编辑器,传送门

Dart 支持以下数据类型:

  1. 数字(number)
  2. 字符串(string)
  3. 布尔值(boolean)
  4. 列表(list)
  5. 集合(set)
  6. 映射(map)
  7. 符文(rune)
  8. 符号(Symbol)

数字(number)

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<int> arr = [1,2,3];

你也可以使用构造函数定义一个列表:

var ls = new List();
print(ls);//[]

构造函数创建的 List 对象同样可以指明类型,一旦指明则无法添加其他类型数据:

var ls = new List<String>();
// 取消注释则会报错
// ls.add(1);

但要注意,一旦声明了 int 类型,你就无法添加其他类型的值:

// "4" String
List<int> arr = [1,2,3,"4"];
// Error: Compilation failed.

Dart 中的 List 字面量非常像 JavaScript 中的 array 字面量,所以你尽可能让 Dart 自动推断类型:

var arr = [1,2,3];

注意,Dart 推断 arr 的类型为 List<int> 。 如果尝试将非整数对象添加到此 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 <String> cls = {"小王", "小杨"}; 

但要注意,一旦声明了 String 类型,你就无法添加其他类型的值:

Set <String> cls = {"小王", "小杨", true}; 
// Error: Compilation failed.

采用字面量方式创建,即 var 关键字:

var cls = {true,false};

注意,Dart 推断 cls 的类型为 Set<bool> 。 如果尝试将非布尔对象添加到此 Set 中,则分析器或运行时会引发错误,就像上面所述(Error: Compilation failed.)。

如果你想定义 Set 类型的编译时常量,那么你需要在 Set 字面量之前添加 const 关键字:

final b = const {
   "one",
   "tow"
};
// 尝试运行时添加
b.add("three");// Cannot change unmodifiable set

要创建一个空集,使用前面带有类型参数的 {} ,或者将 {} 赋值给 Set 类型的变量:

Set <int> a = {};
var b = <String>{};
// test
print(a);//{}
print(b);//{}

注意,初学者可能很容易和下面要介绍的 Map ,也就是 Object(对象)混淆,这两者语法非常相似, 因为先有的 Map 字母量语法,所以 {} 默认是 Map 类型。

这样写,就是创建的空 Map 对象而不是 Set 对象,请注意语法上的细节:

var obj = {};
print(obj.runtimeType.toString());//JsLinkedHashMap<dynamic, dynamic>
// 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<String, String>,nobleGases 的类型推断为 Map<int, String> 。 如果你尝试在上面的 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 字面量是编译时常量。

发布了238 篇原创文章 · 获赞 363 · 访问量 77万+

猜你喜欢

转载自blog.csdn.net/weixin_44198965/article/details/103927366