1.前言
在学习 Dart 语言时, 应该基于以下事实和概念:
-
任何保存在变量中的都是一个 对象 , 并且所有的对象都是对应一个 类 的实例。 无论是数字,函数和
null
都是对象。所有对象继承自 Object 类。 -
尽管 Dart 是强类型的,但是 Dart 可以推断类型,所以类型注释是可选的。 在上面的代码中,
number
被推断为int
类型。 如果要明确说明不需要任何类型, 需要使用特殊类型dynamic
。 -
Dart 支持泛型,如
List <int>
(整数列表)或List <dynamic>
(任何类型的对象列表)。 - Dart 支持顶级函数(例如
main()
), 同样函数绑定在类或对象上(分别是 静态函数 和 实例函数 )。 以及支持函数内创建函数 ( 嵌套 或 局部函数 ) 。 - 类似地, Dart 支持顶级 变量 , 同样变量绑定在类或对象上(静态变量和实例变量)。 实例变量有时称为字段或属性。
- 与 Java 不同,Dart 没有关键字 “public” , “protected” 和 “private” 。 如果标识符以下划线(_)开头,则它相对于库是私有的。 有关更多信息,参考 库和可见性。
- 标识符 以字母或下划线(_)开头,后跟任意字母和数字组合。
- Dart 语法中包含 表达式( expressions )(有运行时值)和 语句( statements )(没有运行时值)。 例如,条件表达式
condition ? expr1 : expr2
的值可能是expr1
或expr2
。 将其与 if-else 语句 相比较,if-else 语句没有值。 一条语句通常包含一个或多个表达式,相反表达式不能直接包含语句。 -
Dart 工具提示两种类型问题:警告_和_错误。 警告只是表明代码可能无法正常工作,但不会阻止程序的执行。 错误可能是编译时错误或者运行时错误。 编译时错误会阻止代码的执行; 运行时错误会导致代码在执行过程中引发 [异常](#exception)。
2.关键字
3.变量
(1)创建变量
- var定义变量,通过这种方式定义变量不需要指定变量类型。
-
var name="xlx"
- b变量仅存储对象引用,这里的name存储了一个String类型的对象的引用。"xlx"是这个String类型对象值
-
- 动态类型:
-
dynamic name="xlx"
dynamic ist=true
-
- 显式声明:
-
String name = "xlx"
-
(2)默认值
未初始化的变量默认值是 null
。即使变量是数字 类型默认值也是 null,因为在 Dart 中一切都是对象,数字类型 也不例外。
(3)FInal和Const
- Final 变量的值只能被设置一次
- Const 变量在编译时就已经固定 (Const 变量 是隐式 Final 的类型.)
- 相同的值,final变量会重复创建,const会引用同一份值
-
编译时变量:常量的值在编译时知道,不需要等到程序运行的时候
-
运行时常量:常量的值只能在运行时知道
(4)内置类型
dart语言支持以下内建类型:
- Number
- String
- Boolean
- List(Array)
- Map
- Set
- Rune(用于在字符串中表示Unicode字符)
- Symbol
这些类型都可以被初始化为字面量。例如, 'this is a string'
是一个字符串的字面量, true
是一个布尔的字面量。
因为在 Dart 所有的变量终究是一个对象(一个类的实例), 所以变量可以使用 构造涵数 进行初始化。 一些内建类型拥有自己的构造函数。 例如, 通过 Map()
来构造一个 map 变量。
①Number
Dart的Number有两种类型
- int:整数值不大于64位, 具体取决于平台。 在 Dart VM 上, 值的范围从 -263 到 263 - 1. Dart 被编译为 JavaScript 时,使用 JavaScript numbers, 值的范围从 -253 到 253 - 1.
- double:64位(双精度)浮点数,依据 IEEE 754 标准。
int
和 double
都是 num
. 的亚类型。 num 类型包括基本运算 +, -, /, 和 *, 以及 abs()
, ceil()
, 和 floor()
, 等函数方法。 (按位运算符,例如»,定义在 int 类中。) 如果 num 及其亚类型找不到你想要的方法, 尝试查找使用 dart:math 库。
②String
- Dart 字符串是一组 UTF-16 单元序列。 字符串通过单引号或者双引号创建。
- 字符串可以通过
${
expression
}
的方式内嵌表达式。——类似JS的模板字符串 - 在 Dart 中通过调用就对象的
toString()
方法来得到对象相应的字符串。(也可以使用[1],length等方法实现字符串操作) - 使用连续三个单引号或者三个双引号实现多行字符串对象的创建
-
String a = """ 你选的嘛,偶像 """;
- 使用
r
前缀,可以创建 “原始 raw” 字符串:(即解析其中的转义字符串) -
更多关于 string 的使用, 参考 字符串和正则表达式.
③Boolean
- Dart 只有字面量
true
andfalse
是布尔类型, 这两个对象都是编译时常量
④List
- Dart 中的 List 字面量非常像 JavaScript 中的 array 字面量
-
var list = [1, 2, 3];
- Dart 推断
list
的类型为List<int>
。 如果尝试将非整数对象添加到此 List 中, 则分析器或运行时会引发错误。 有关更多信息,请阅读 类型推断。- 即list定义时如果全都是字符串,推断当前list就是字符串数组(dynamic泛型表示所有类型)
⑤Set
- 在 Dart 中 Set 是一个元素唯一且无序的集合。 Dart 为 Set 提供了 Set 字面量和 Set 类型。
-
var h = {"aaa", "bbb", "ccc", "ddd"}; var hh = ["aaa", "bbb", "ccc", "ddd"]; h.add("aaa"); hh.add("aaa"); print(h); // {aaa, bbb, ccc, ddd} print(hh); // [aaa, bbb, ccc, ddd, aaa]
- 要创建一个空集,使用前面带有类型参数的
{}
,或者将{}
赋值给Set
类型的变量: -
Set<String> names = {}; // 方法1 var ns = <String>{};
⑥Map
- 通常来说, Map 是用来关联 keys 和 values 的对象
- keys 和 values 可以是任何类型的对象。在一个 Map 对象中一个 key 只能出现一次。 但是 value 可以出现多次。
- Dart 中 Map 通过 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>
。
- Dart 会将
- 以上 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';
- 这里为什么只有
Map()
,而不是使用new Map()
。 因为在 Dart 2 中,new
关键字是可选的。 有关更多信息,参考 构造函数的使用。 - 如果 Map 中不包含所要查找的 key,那么 Map 返回 null
⑦Rune
- 在 Dart 中, Rune 用来表示字符串中的 UTF-32 编码字符。
4.函数
- Dart 是一门真正面向对象的语言, 甚至其中的函数也是对象,并且有它的类型 Function 。 这也意味着函数可以被赋值给变量或者作为参数传递给其他函数。
-
bool isBool(int x) { return x > 10; }
- 如果函数只有一句表达式,可以使用箭头语法:
- 函数有两种参数类型: required 和 optional。 required 类型参数在参数最前面, 随后是 optional 类型参数。
- list 或 map 可以作为默认值传递。
(1)main()函数
- 任何应用都必须有一个顶级
main()
函数,作为应用服务的入口。main()
函数返回值为空,参数为一个可选的List<String>
。
(2)函数是一等对象
- 一个函数可以作为另一个函数的参数
-
void main() { void printElement(int element) { print(element); } var list = [1, 2, 3]; // 将 printElement 函数作为参数传递。 list.forEach(printElement); }
-
(3)匿名函数
- 匿名函数和命名函数看起来类似— 在括号之间可以定义一些参数或可选参数,参数使用逗号分割。
-
var list = ["aaa", "bbb", "ccc"]; list.forEach((e) { print(e); });
(4)作用域
- Dart 是一门词法作用域的编程语言,就意味着变量的作用域是固定的, 简单说变量的作用域在编写代码的时候就已经确定了。 花括号内的是变量可见的作用域。
-
void main() { var insideMain = true; void myFunction() { var insideFunction = true; void nestedFunction() { var insideNestedFunction = true; } } }
注意
nestedFunction()
可以访问所有的变量, 一直到顶级作用域变量。
(5)闭包
- 闭包就是一个函数对象,及时函数对象的调用在它原始作用域之外,也能访问在它词法作用域内的变量