一、基础概念

  • 任何保存在变量中的都是一个 对象 , 并且所有的对象都是对应一个 的实例。 无论是数字,函数和 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 的值可能是 expr1expr2 。 将其与 if-else 语句 相比较,if-else 语句没有值。 一条语句通常包含一个或多个表达式,相反表达式不能直接包含语句。
  • Dart 工具提示两种类型问题:警告错误。 警告只是表明代码可能无法正常工作,但不会阻止程序的执行。 错误可能是编译时错误或者运行时错误。 编译时错误会阻止代码的执行; 运行时错误会导致代码在执行过程中引发 [异常](#exception)。

二、入口函数

Dart 的入口函数跟 C 相同, 就是 main 函数:

  1. main() {
  2. ...
  3. }

三、变量与常量

  1. // 变量
  2. var i = 0;
  3. int a = 10; // 指定类型
  4. // 常量
  5. const pi = 3.14;
  6. final name = 'xiaoyu';
  7. final String name = 'xiaoyu';

:::info 提示: 实例变量可以是 final 类型但不能是 const 类型。 必须在构造函数体执行之前初始化 final 实例变量 —— 在变量声明中,参数构造函数中或构造函数的初始化列表中进行初始化。 :::

动态类型

name 变量的类型被推断为 String 。 但是也可以通过指定类型的方式,来改变变量类型。 如果对象不限定为单个类型,可以指定为 对象类型动态类型

  1. dynamic name = 'xiaoyu';
  2. name = 888;
  1. Object name = 'xiaoyu';
  2. name = 888;

:::info 如果使用 var 或 类型 声明的变量,是不可以对其赋值其他类型的值。 :::

  1. var name = 'xiaoyu';
  2. name = 888; // 报错 Error: A value of type 'int' can't be assigned to a variable of type 'String'.
  1. String name = 'xiaoyu';
  2. name = 888; // 报错 Error: A value of type 'int' can't be assigned to a variable of type 'String'.

四、控制流程

控制流程跟 js 类似,这里只是说一下不同的地方,基础知识不再赘述。详情可参考:控制流程语句

条件语句的显式判断

在 if 条件句中,需要显式对条件判定(判定结果必须为布尔值),比如:

  1. // 错误的示例
  2. var name = 'Bob';
  3. if (name) {
  4. // Prints in JavaScript, not in Dart.
  5. print('You have a name!');
  6. }
  7. // 正确的示例
  8. var name = 'Bob';
  9. if (name == 'Bob') {
  10. print('You have a name!');
  11. }

在 JS 中两种示例都能正常执行,但 Dart 只有下面的示例可以如期执行,虽然我并不习惯这样的设定。

case 语句的继续执行

如果你需要实现这种继续到下一个 case 语句中继续执行,则可以 使用 continue 语句跳转到对应的标签(label)处继续执行:

  1. var command = 'CLOSED';
  2. switch (command) {
  3. case 'CLOSED':
  4. executeClosed();
  5. continue nowClosed;
  6. // Continues executing at the nowClosed label.
  7. nowClosed:
  8. case 'NOW_CLOSED':
  9. // Runs for both CLOSED and NOW_CLOSED.
  10. executeNowClosed();
  11. break;
  12. }

循环条件

如果对象实现了 Iterable 接口 (例如,list 或者 set)。 那么可以在循环中添加循环条件:

  1. var arr = ['This', 'is', 'a', 'long', 'string'];
  2. arr
  3. .where((str) => str.length > 3)
  4. .forEach((element) => print(element));

输出:

  1. This
  2. long
  3. string

上面的循环等价于:

  1. for(var str in arr) {
  2. if (str.length <= 3) continue;
  3. print(str);
  4. }

五、运算符

级联操作

级联操作用 2 个点(..)表示,可对同一对象执行一系列操作。类似于 JavaScript 中的链式操作(比如jQuery)。

级联操作的作用主要是为了简化代码。

  1. query('#btn1') // 获取一个id为btn1的按钮对象
  2. ..text='确定'
  3. ..classes.add('Button1Style')
  4. ..onClick.listen((s) => window.alert('ok'));

等价于:

  1. var btn1=query('#btn1'); // 获取一个id为btn1的按钮对象
  2. btn1.text='确定';
  3. btn1.classes.add('Button1Style');
  4. btn1.onClick.listen((s) => window.alert('ok'));

判空运算符

判空运算符为 ??

  1. var a;
  2. print(a); // null
  3. print(a ?? 0); // 0
  4. a = 1;
  5. print(a ?? 0); // 1

类型判定操作符

操作符 解释
as 类型转换
is 如果对象是指定的类型返回 True
is! 如果对象是指定的类型返回 False
  1. var a;
  2. print(a == null); // true
  3. print(a is Object); // true
  4. print(a is List); // false

六、关键字

Dart 语言关键字列表。

abstract dynamic implements show
as else import static
assert enum in super
async export interface switch
await extends is sync
break external library this
case factory mixin throw
catch false new true
class final null try
const finally on typedef
continue for operator var
covariant Function part void
default get rethrow while
deferred hide return with
do if set yield

参考资料