前言
基本类型是语言的基础。
- Dart 语言支持以下基础类型:
- Numbers(int、double), 整形
- Strings(String), 字符串
- Booleans(bool) , 布尔型
- Records((value1,value2)) 记录
- Lists(List ) 数组
- Sets(Set) 集合
- Maps(Map) 映射
- Runes(Runes,通常由 characters API 代替) 字符
- Symbols(Symbol) 符号型
- null (Null) 空值
因为 Dart 中的每个变量都指向一个对象–一个类的实例–所以通常可以使用构造函数来初始化变量。
其他一些类型在 Dart 语言中也有特殊作用:
- Object : 除 Null 外所有 Dart 类的超类
- Enum : 所有枚举的超类。
- Future and Stream : 用于异步支持。
- Iterable : 用于for-in loops 和 同步的 generator functions。
- Never : 表示表达式永远无法成功完成求值。最常用于总是抛出异常的函数。
- dynamic : 表示要禁用静态检查。通常应使用 Object 或 Object?。
- void :表示某个值从未使用过, 通常用作返回类型。
基础类型介绍
Numbers - int
整数值不大于 64 位,具体取决于平台。在本地平台上,数值范围为 -263 至 263 - 1。在web上,整数值以 JavaScript 数(64 位浮点数值,不含小数部分)表示,数值范围为 -253 至 253 - 1。
Number-double
IEEE 754 标准规定的 64 位(双精度)浮点数。就是小数
int 和 double 都是 num 的子类型。num 类型包括基本运算符,如 +、-、/ 和 *,还包括 abs()、ceil() 和 floor() 等方法(位运算符,如 >> 在 int 类中定义)。(如果 num 及其子类型中没有你想要的内容,dart:math 库可能会有。
void numFn() {
int age = 18;
double pi;
pi = 3.14;
age = 17;
print("${pi},${age}");
}
您也可以将变量声明为 num。如果这样做,变量就既可以有整数值,也可以有小数值:
num x = 1;
x += 2.5;
String 字符串
一个 Dart 字符串(String 对象)包含一个 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 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.";
print("${s1}${s2} ${s3} ${s4.toUpperCase()}");
可以使用相邻字符串字面量或 + 运算符来连接字符串:
var s5 = 'zsk' '666' '嘿嘿';
var s6 = 'zsk' + '18';
print(s5);
print(s6);
另一种创建多行字符串的方法:使用带单引号或双引号的三引号:
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.';
var ss = 'In a raw string, not even \n gets special treatment.';
print(s);
print(ss);
字面字符串是编译时常量,只要任何插值表达式是求值为空或数值、字符串或布尔值的编译时常量即可。
const aConstNum = 12;
const aConstBool = true;
const aConstString = 'a constant string';
const validConstString = 'asdasd$aConstNum asd$aConstBool 哈哈$aConstString';
print(validConstString);
Booleans 布尔型
为了表示布尔值,Dart 提供了一种名为 bool 的类型。只有两个对象具有 bool 类型:布尔字面量 true 和 false,它们都是编译时常量。
Runes and grapheme clusters 符文和词组
在 Dart 中,符文揭示了字符串的 Unicode 代码点。您可以使用字符包来查看或操作用户感知的字符,也称为 Unicode(扩展)词组。
Unicode 为世界上所有书写系统中使用的每个字母、数字和符号定义了唯一的数值。由于 Dart 字符串是 UTF-16 代码单元的序列,因此在字符串中表达 Unicode 代码点需要特殊的语法。表达 Unicode 代码点的通常方法是 \uXXXX,其中 XXXX 是 4 位十六进制值。例如,心形字符(♥)就是 \u2665。要指定多于或少于 4 位十六进制数,请将数值置于大括号中。例如,大笑表情符号 就是 \u{1f606}。
var hh = '哈哈哈哈 \u{1f606} !';
var loveXin = '\u{2665}';
print(hh + loveXin);
Symbols
符号对象代表 Dart 程序中声明的运算符或标识符。您可能永远都不需要使用符号,但对于通过名称来引用标识符的 API 来说,符号是非常宝贵的,因为最小化会改变标识符名称,但不会改变标识符符号。
要获取标识符的符号,可使用符号文字,即 # 后跟标识符:
#radix
#bar
符号字面量是编译时常量。
这和js的Symbol作用相似。
Records 记录
记录要求语言版本至少为 3.0。
记录是一种匿名、不可变的集合类型。与其他集合类型一样,记录可以将多个对象捆绑成一个对象。与其他集合类型不同,记录是固定大小、异构和类型化的。
记录是真实的值;你可以将它们存储在变量中、嵌套它们、将它们传递给函数或从函数中传递它们,还可以将它们存储在数据结构(如列表、映射和集合)中。
记录表达式是以逗号分隔的命名或位置字段列表,用括号括起来:
var record = ('first', a: 2, b: true, 'last');
记录类型注释是以逗号分隔的类型列表,用括号括起来。您可以使用记录类型注解来定义返回类型和参数类型。例如,以下 (int, int) 语句就是记录类型注解:
(int, int) swap((int, int) record) {
var (a, b) = record;
return (b, a);
}
记录表达式和类型注解中的字段反映了函数中参数和参数的工作方式。位置字段直接放在括号内, 如果你前面注解了类型和位置个数,不能再增加。
如果你想在记录中指定对象的参数如下:
在记录类型注释中,命名字段位于类型和名称成对的大括号分隔部分内,在所有位置字段之后。在记录表达式中,名称放在每个字段值的前面,后面是冒号。
// Record type annotation in a variable declaration:
({int a, bool b}) record;
// Initialize it with a record expression:
record = (a: 123, b: true);
记录类型中已命名字段的名称是记录类型定义或记录形状的一部分。两个记录的命名字段名不同,其类型也就不同:
// 这两个不相等
({int a, int b}) recordAB = (a: 1, b: 2);
({int x, int y}) recordXY = (x: 3, y: 4);
在记录类型注释中,您也可以为位置字段命名,但这些名称纯粹是为了记录,并不影响记录的类型,意思是,如果值不是键值对的那种,注解时命名字段没屁用就看看。
(int a, int b) recordAB = (1, 2);
(int x, int y) recordXY = (3, 4);
recordAB = recordXY; // OK.
获取记录里的值
记录字段可通过内置的获取器访问。记录是不可变的,因此字段没有设置器。意思是只能获取,不能改变。
已命名字段使用同名的获取器。位置字段使用名称为 $ 的获取器,而不使用命名字段:
var record = ('first', a: 2, b: true, 'last');
print(record.$1); // Prints 'first'
print(record.a); // Prints 2
print(record.b); // Prints true
print(record.$2); // Prints 'last'
记录里的类型
单个记录类型没有类型声明。记录是根据其字段类型进行结构类型化的。记录的形状(字段集、字段类型及其名称(如有))唯一地决定了记录的类型。
记录中的每个字段都有自己的类型。同一记录中的字段类型可能不同。无论从记录中访问哪个字段,类型系统都会知道每个字段的类型:
(num, Object) pair = (42, 'a');
var first = pair.$1; // Static type `num`, runtime type `int`.
var second = pair.$2; // Static type `Object`, runtime type `String`.
记录相等性
如果两条记录具有相同的形状(字段集),且相应字段的值相同,则这两条记录是相等的。由于已命名字段的顺序不是记录形状的一部分,因此已命名字段的顺序不会影响相等性。
(int x, int y, int z) point = (1, 2, 3);
(int r, int g, int b) color = (1, 2, 3);
print(point == color); // Prints 'true'.
({int x, int y, int z}) point = (x: 1, y: 2, z: 3);
({int r, int g, int b}) color = (r: 1, g: 2, b: 3);
print(point == color); // Prints 'false'. Lint: Equals on unrelated types.
记录在函数中返回
记录允许函数将多个值捆绑在一起返回。要从返回值中检索记录值,可使用模式匹配将值重组为局部变量。
// 创建一个函数,返回类型(String,int)的记录
(String, int) userInfo(Map<String, dynamic> json) {
return (json['name'] as String, json['age'] as int);
}
// 使用
final json = <String, dynamic>{
'name': 'ZSK',
'age': 10,
'color': 'blue',
};
print(userInfo(json));
Collections 集合
lists列表
在几乎所有编程语言中,最常见的集合可能就是数组或有序的对象组。在 Dart 中,数组是 List 对象,因此大多数人都称其为列表。
Dart 列表的字面形式是用逗号分隔的表达式或值列表,并用方括号([])括起来。下面是一个简单的 Dart list:
这个列表是有类型的,像下面的就会推断成整数类型的列表,增加只能增加相同类型的数据。
var list = [1, 2, 3];
列表使用基于零的索引,其中 0 是第一个值的索引,list.length - 1 是最后一个值的索引。您可以使用 .length 属性获取列表的长度,并使用下标操作符([])访问列表的值:
var list = [
'Car',
'Boat',
'Plane',
];
要创建一个编译时常量的 list,请在 list 字面之前添加 const:
var constantList = const [1, 2, 3];
// constantList[1] = 1; // This line will cause an error.
Sets 集合
Dart 中的集合是由唯一项组成的无序集合。Dart 通过集合文字和集合类型提供对集合的支持。
下面是一个简单的 Dart 集合,使用集合字面量创建:
要创建空集,可在类型参数前使用 {},或将 {} 赋值给 Set 类型的变量:
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
var names = <String>{};
// Set<String> names = {}; // 这样也可以
// var names = {}; // 这样不行,这是声明的map.
映射字面量的语法与集合字面量的语法类似。由于 map 字面量出现在前面,{} 默认为 Map 类型。如果您忘记了 {}
的类型注解或它所赋值的变量,那么 Dart 将创建一个 Map<dynamic, dynamic> 类型的对象。
使用 add() 或 addAll() 方法将项目添加到现有集合中:
var elements = <String>{};
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
elements.add('fluorine');
elements.addAll(halogens);
使用 .length 获取集合中的项目数:
assert(elements.length == 5);
要创建一个编译时常量的集合,请在集合字面之前添加 const:
final constantSet = const {
'fluorine',
'chlorine',
'bromine',
'iodine',
'astatine',
};
// constantSet.add('helium'); // This line will cause an error.
Maps
一般来说,映射是一个关联键和值的对象。键和值都可以是任何类型的对象。每个键只能出现一次,但可以多次使用同一个值。Dart 对映射的支持由映射字面量和映射类型提供。
下面是几个简单的 Dart map,都是使用map字面量创建的:
var gifts = {
// Key: Value
'first': 'partridge',
'second': 'turtledoves',
'fifth': 'golden rings'
};
var nobleGases = {
2: 'helium',
10: 'neon',
18: 'argon',
};
Dart 推断 gifts 为 Map<String, String> 类型,而 nobleGases 为 Map<int, String> 类型。如果您尝试向任一映射添加错误类型的值,分析器或运行时将引发错误。有关详细信息,请阅读类型推断。
您可以使用 Map 构造函数创建相同的对象:
var gifts = Map<String, String>();
gifts['first'] = 'partridge';
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings';
var nobleGases = Map<int, String>();
nobleGases[2] = 'helium';
nobleGases[10] = 'neon';
nobleGases[18] = 'argon';
如果您来自 C# 或 Java 等语言,您可能会希望看到 new Map() 而不仅仅是 Map()。在 Dart 中,new 关键字是可选的。详情请参阅使用构造函数。
使用下标赋值操作符([]=)向现有映射添加新的键值对:
var gifts = {'first': 'partridge'};
gifts['fourth'] = 'calling birds'; // Add a key-value pair
使用下标操作符([])从地图中读取值,如果查找的键不在地图中,则返回空值:
var gifts = {'first': 'partridge'};
assert(gifts['first'] == 'partridge');
// 不存在
assert(gifts['fifth'] == null);
使用 .length 获取映射中键值对的数量:
var gifts = {'first': 'partridge'};
gifts['fourth'] = 'calling birds';
assert(gifts.length == 2);
要创建一个编译时常量的映射,请在映射字面之前添加 const:
final constantMap = const {
2: 'helium',
10: 'neon',
18: 'argon',
};
相关操作
- 展开符。Dart 支持 list、map 和 set 字面中的展开操作符(…)和空感知展开操作符(…?展开操作符为在集合中插入多个值提供了一种简洁的方法。
var list = [1, 2, 3];
var list2 = [0, ...list];
assert(list2.length == 4);
var list2 = [0, ...?list3];
assert(list2.length == 1);
- 流程控制。 Dart 提供了用于 list、map 和 set 字面的集合 if 和集合 for。您可以使用这些操作符通过条件(if)和重复(for)来构建集合。
var nav = ['Home', 'Furniture', 'Plants', if (promoActive) 'Outlet'];
var nav = ['Home', 'Furniture', 'Plants', if (login case 'Manager') 'Inventory'];
var listOfInts = [1, 2, 3];
var listOfStrings = ['#0', for (var i in listOfInts) '#$i'];
assert(listOfStrings[1] == '#1');
结语
结束了。