一、基础概念
- 任何保存在变量中的都是一个 对象 , 并且所有的对象都是对应一个 类 的实例。 无论是数字,函数和
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)。
二、入口函数
Dart 的入口函数跟 C 相同, 就是 main 函数:
main() {
...
}
三、变量与常量
// 变量
var i = 0;
int a = 10; // 指定类型
// 常量
const pi = 3.14;
final name = 'xiaoyu';
final String name = 'xiaoyu';
:::info 提示: 实例变量可以是 final 类型但不能是 const 类型。 必须在构造函数体执行之前初始化 final 实例变量 —— 在变量声明中,参数构造函数中或构造函数的初始化列表中进行初始化。 :::
动态类型
name
变量的类型被推断为 String
。 但是也可以通过指定类型的方式,来改变变量类型。 如果对象不限定为单个类型,可以指定为 对象类型
或 动态类型
。
dynamic name = 'xiaoyu';
name = 888;
Object name = 'xiaoyu';
name = 888;
:::info 如果使用 var 或 类型 声明的变量,是不可以对其赋值其他类型的值。 :::
var name = 'xiaoyu';
name = 888; // 报错 Error: A value of type 'int' can't be assigned to a variable of type 'String'.
String name = 'xiaoyu';
name = 888; // 报错 Error: A value of type 'int' can't be assigned to a variable of type 'String'.
四、控制流程
控制流程跟 js 类似,这里只是说一下不同的地方,基础知识不再赘述。详情可参考:控制流程语句
条件语句的显式判断
在 if 条件句中,需要显式对条件判定(判定结果必须为布尔值),比如:
// 错误的示例
var name = 'Bob';
if (name) {
// Prints in JavaScript, not in Dart.
print('You have a name!');
}
// 正确的示例
var name = 'Bob';
if (name == 'Bob') {
print('You have a name!');
}
在 JS 中两种示例都能正常执行,但 Dart 只有下面的示例可以如期执行,虽然我并不习惯这样的设定。
case 语句的继续执行
如果你需要实现这种继续到下一个 case 语句中继续执行,则可以 使用 continue 语句跳转到对应的标签(label)处继续执行:
var command = 'CLOSED';
switch (command) {
case 'CLOSED':
executeClosed();
continue nowClosed;
// Continues executing at the nowClosed label.
nowClosed:
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeNowClosed();
break;
}
循环条件
如果对象实现了 Iterable 接口 (例如,list 或者 set)。 那么可以在循环中添加循环条件:
var arr = ['This', 'is', 'a', 'long', 'string'];
arr
.where((str) => str.length > 3)
.forEach((element) => print(element));
输出:
This
long
string
上面的循环等价于:
for(var str in arr) {
if (str.length <= 3) continue;
print(str);
}
五、运算符
级联操作
级联操作用 2 个点(..)表示,可对同一对象执行一系列操作。类似于 JavaScript 中的链式操作(比如jQuery)。
级联操作的作用主要是为了简化代码。
query('#btn1') // 获取一个id为btn1的按钮对象
..text='确定'
..classes.add('Button1Style')
..onClick.listen((s) => window.alert('ok'));
等价于:
var btn1=query('#btn1'); // 获取一个id为btn1的按钮对象
btn1.text='确定';
btn1.classes.add('Button1Style');
btn1.onClick.listen((s) => window.alert('ok'));
判空运算符
判空运算符为 ??
var a;
print(a); // null
print(a ?? 0); // 0
a = 1;
print(a ?? 0); // 1
类型判定操作符
操作符 | 解释 |
---|---|
as |
类型转换 |
is |
如果对象是指定的类型返回 True |
is! |
如果对象是指定的类型返回 False |
var a;
print(a == null); // true
print(a is Object); // true
print(a is List); // false
六、关键字
Dart 语言关键字列表。