操作符
- 除法( / ), 整除(~/)
void main() { print('5/2 = ${5 / 2}'); // 5/2 = 2.5 print('5~/2 = ${5 ~/ 2}'); // 5~/2 = 2 }
- 类型转换(as), 类型判断(is、is!), as 只能从父类型转子类型, is 判断变量是某种类型, is!和is相反,判断变量不是某种类型
void main() { num a = 123; // print(a.isOdd); // error: isOdd 不是num的成员变量 print((a as int).isOdd);// isOdd 是int的成员方法,所有a必须转换成int类型后再调用 print('a is not String ? ${a is! String}'); // a is not String ? true print('a is int ? ${a is int}'); // a is int ? true }
- ??= 为值为null的变量赋值
void main() { var a; a ??= 1; // 赋值前a = null,赋值后 a=1 a ??= 2; // 赋值前 a = 1, 赋值后 a=1 print(a); // 1 }
- expr1 ?? expr2, 等价于 expr1 != null ? expr1 : expr2
void main() { var a; var b = 1; print(a ?? b); // 1 a = 0; print(a ?? b); // 0 }
- 级联操作(
..
)可以在同一个对象上连续调用多个函数及访问成员变量
// '..'不同于'.',不要求函数有返回值,'..'相当于普通函数执行后返回‘this’ class Car { void move(String direction, double distance) { print('小汽车向${direction}行驶了${distance} 千米'); } Car run(String direction, double distance) { print('小汽车向${direction}行驶了${distance} 千米'); return this; } } void main() { Car car = new Car(); car..move('东', 3)..move('南', 4)..move('西', 4)..move('北', 4); car..move('东', 3)..run('西', 3)..run('北', 4).run('西', 4).run('北', 4); }
- a?.b 如果a为null,则返回null,否则返回a.b
void main() { int a; // print(a.isOdd); // error: a未赋值,不能访问成员变量和成员函数 print(a?.isOdd); // 相当于 if (a == null) { print(null); } else { print(a.isOdd); } }
类
- 每个对象都是一个类的实例,所有的类都集成于Object
void main() { int a = 1; print(a is Object); // true }
- 每个类都只能有一个父类,但是可以同时实现多个接口,一个父类可以同时被多个子类继承
class Tiger extends Animal implements Fly, Swim { // todo } class Dog extends Animal { // todo }
- 每个实例变量都会自动生成一个getter方法,Non-final实例变量还会自动生成一个setter方法
class Test { int a; // 相当于 // int _a; // int get a => _a; // set a(int val) => this._a = val; }
- 定义一个和类名字一样的方法就定义了一个构造函数,还可以带有其他可选的标识符,如果没有定义,会生成一个不带参数的默认构造函数,构造函数不会被继承
class Parent { String name; Parent(this.name); } class Child extends Parent { Child(String name) : super(name); Child.create(String name) : super(name); } void main(){ var zhangsan = Child('张三'); var lisi = Child.create('李四'); }
- 可以使用abstract来定义抽象类,抽象类不能被实例化。抽象类通常含有抽象方法,抽象方法只有方法签名,没有实现。
abstract class Animal { // 抽象方法 void moving(); }
- 用extends来实现继承,用implements来实现接口,使用@override来重新父类方法
class Animal { final String name; Animal(this.name); void moving() { print('${this.name}正在移动'); } } abstract class Fly { // 抽象方法 void fly(); } class Tiger extends Animal implements Fly { Tiger() : super('老虎'); @override void fly() { print('如虎添翼'); } }
- 用static定义静态变量和静态方法
class Calculator { static int Add(int m, int n) { return m + n; } } void main(){ print(Calculator(1, 2)); }
库的使用
- 通过
import
来引入库
- 引用内部库
import 'dart:schema'
,如:import 'dart:io';
- 引用外部库
import 'package:schema'
, 如:import 'package:utils/utils.dart';
- 可以通过
as
来指定库前缀,如import 'package:utils/utils.dart' as utils;
- 可以通过
show
和hide
来部分导入库
- 可以通过
deferred as
延迟加载一个库
dart 核心库
dart:core
提供了基础类型、集合和其他少量但是非常核心的功能,dart应用会自动导入这个库。
dart:convert
提供了一些用来转换 JSON 和 UTF-8 的转换器,还可以自定义 新的转换器。
dart:async
异步编程通常使用回调函数,但是 Dart 提供了另外的 选择: Future 和 Stream 对象。
dart:html
为基于web的应用提供了操作Dom元素和使用HTML5 API的功能。
dart:math
提供了常用的数学运算功能。
dart:io
提供了一下文件读写、进程访问、sockets等相关的功能,只有命令行应用可以使用。
PUB
pub类似于node的npm,用于管理dart应用的包,详情参见pub.dev/
总结
了解了上面这些基础语法,基本上就可以看懂一些dart示例和源码了,想有所成,了解这些还是远远不够的,但是这些可以作为一个开始,作为学习dart的起点。
参考
- 官方文档:dart.dev/guides
- Pub网站: pub.dev/
- 中文官网:dart.goodev.org/