Dart 学习笔记
官方文档:https://dart.cn/guides
在线测试:https://dartpad.cn/
Dart 与我熟悉的 C#和 JS 也相似,这里大部分记录 Dart 与其他编程语言的区别,或 Dart 的特点
构造函数
语法糖
Dart 的构造函数支持一种语法糖,能够简单给成员变量赋值
1 | DemoClass(this.name, this.age) { |
初始化列表
在构造函数中为成员变量赋值
1 | DemoClass(nameParam, ageParam) |
在开发模式下,可以在初始化列表中使用 assert 来验证输入数据
1 | DemoClass.withAssert(this.nameParam, this.ageParam) : assert(x >= 0) { |
命名构造函数
可以指定构造函数名
1 | DemoClass.name(String name) : this(name, null); |
常量构造函数
如果类生成的对象是不变的,在构造函数前加const
,该类的实例变量均为final
工厂构造函数
使用factory
关键字标识构造函数,变为工厂构造函数。
工厂构造函数需要返回一个实例,作用类似于 _C#的静态函数返回实例_,但与 C#静态函数不同的是,Dart 的工厂构造函数与普通的构造函数调用方式相同。
1 | class Logger { |
创建类
new 关键字
new 关键字是可选的
1 | var obj1 = new DemoClass('aaa',12) |
调用父类构造函数
使用: super.[父类构造函数]
1 | Child.name(String name) : super.name(name) { |
final & const
final
或者 const
修饰的变量都不能被修改,但final
可被赋值一次。
const
是编译时常量,final
只能在声明时赋值,或者在构造函数中的初始化列表中赋值。
const
变量也是final
变量。
const
关键字不仅仅可以用来定义常量,还可以用来创建 常量值,该常量值可以赋予给任何变量。
1 | const a = []; // 常量,可修改数组内容,但不能重新给a赋值 |
使用时,dart 中的final
像 JS 中的const
,dart 中的const
像 C#中的const
Getters & setters
与 JS 类似
实例对象的每个属性都有隐式的Getter
方法。非final
属性有Setter
方法。
可使用 get
和 set
关键字单独添加Getter
和Setter
方法
1 | class Rectangle { |
隐式接口
每个类都有个隐式接口,通过关键之implements
可实现类的隐式接口。
即仅需要类的定义,但不要其内部实现。
1 | class Point implements Comparable, Location {/*...*/} |
继承
使用extends
关键字
1 | class OtherClass extends DemoClass { |
Dart 是单继承的。使用super
关键字调用父类。
重写
使用 @override
注解
1 | class OtherClass extends DemoClass { |
noSuchMethod
如果调用了对象上不存在的方法或实例变量将会触发 noSuchMethod
方法,可以重写 noSuchMethod
方法来追踪和记录这一行为
1 | class A { |
Extension 方法
使用extension
/on
关键字。与 C#的扩展方法作用相同。
1 | extension NumberParsing on String { |
枚举
1 | enum Color { red, green, blue } |
枚举包含index
获取索引
1 | assert(Color.red.index == 0); |
枚举类包含values
方法获取枚举值列表
1 | List<Color> colors = Color.values; |
Mixin
类似于 C#中的接口,但与接口不同的是,写法与普通类相同,功能也与普通类相同,比接口更丰富。
定义 mixin 类
定义一个类继承自 Object 并且不为该类定义构造函数,这个类就是 Mixin 类,除非你想让该类与普通的类一样可以被正常地使用,否则可以使用关键字 mixin
替代 class
让其成为一个单纯的 Mixin 类:
1 | mixin MixinClass { |
使用
使用with
关键字让类使用 mixin。
1 |
|
如果使用多个 mixin,用逗号分隔。
指定类
可以使用关键字 on 来指定哪些类可以使用该 Mixin 类
1 | class Musician { |
此处MusicalPerformer
只允许继承Musician
的类使用
可使用多个 mixin 类,用逗号分隔。
泛型
包括泛型类和泛型方法,大多语法与 C#相同,用法也一样。
限制参数化类型
在 C#中在类名后使用where
,在 Dart 中在泛型T
后使用 extends
1 | class SomeClass<T extends SomeBaseClass> { |
无参数泛型
1 | class SomeClass<SomeBaseClass> { |
此时类型为Foo<SomeBaseClass>
字符串
支持单引号和双引号。
插值
支持字符串插值 ${ }
,如果表达式是个标识符,可省略{}
。
1 | const s = '4 + 5 = ${ 4 + 5 }' |
连接
字符串连接用 +
,也可省略 +
。
多行字符串
三个单引号'''
或三个双引号"""
可创建多行字符串
1 | const s = ''' |
转义
加上前缀r
忽略转义字符
1 | var s = r'In a raw string, not even \n gets special treatment.'; |
Lists
自动推断
dart 可自动推断 list 类型
1 | var list = [1, 2, 3]; |
扩展操作符
...
...?
1 | var list = [1, 2, 3]; |
...?
和...
的区别是当数组变量为null
时不会产生异常,此时类似于数组为空数组[]
集合控制流
根据条件创建数组
Collection If
1 | var nav = [ |
Collection For
1 | var listOfInts = [1, 2, 3]; |
级联运算符
级联运算符 ..
,可以在同一个对象上连续调用语句
1 | querySelector('#confirm') // 获取对象 (Get an object). |
相当于
1 | var button = querySelector('#confirm'); |
嵌套
1 | final addressBook = (AddressBookBuilder() |
异常
Dart 提供了 Exception
和 Error
两种类型的异常以及它们一系列的子类。
抛出
可抛出Exception
和 Error
(推荐),也可抛出其他任何对象。
捕获
使用 on
来指定异常类型,使用 catch
来捕获异常对象
1 | try { |
catch
有两个参数,第一个是异常对象,第二个是栈信息 StackTrace
对象。
rethrow
可再次抛出异常
库
导入
与 JS 相同,使用import
关键字。
- dart 内置库:
dart:xxxxxx
- 其他库:
package:xxxxxx
1 | import 'dart:html'; |
指定前缀
如果两个库冲突,可指定前缀
1 | import 'package:lib1/lib1.dart'; |
导入部分
1 | // 只导入 lib1 中的 foo。(Import only foo). |
延迟加载
使用时才会加载,引用时用deferred as
关键字,加载时用loadLibrary
函数
1 | import 'package:greetings/hello.dart' deferred as hello; |
异步
Dart 中的异步分两种
Future
与 C#中的 Task 类似,用法相同。
Stream
与 C#中的 IAsyncEnumerable 类似,用法await for-in
与 C#中的await foreach-in
一样。
其他
- Dart 也有静态方法/变量,关键字与 C#相同
- Dart 没有成员访问限定符,以下划线
_
开头的名命则为私有 变量/方法 - Dart 未初始化的变量全部是
null
,包括int
、double
等 - Dart 支持
for-in
,与 C# 中的foreach-in
相同