1、dart不同于JavaScript的地方是,Dart将所有不为True的值视作False。
2、如果正在重申的变量是可重申的,你可以使用 forEach()方法。如果你不需要知道重申计数器的值,使用forEach()是一个很好的选择:
candidates.forEach((candidate) =>candidate.interview());
3、可重申的类例如Lish以及Set也支持for-in形式的 iteration:
var collection = [0,1,2];
for(var x in collection){
printf(x);
}
4、
if (emp is Person) { // Type check
emp.firstName = 'Bob';
}
你也可以通过as
来简化代码:
(emp as Person).firstName = 'Bob';
注意:上面两段代码并不相等。如果
emp
的值为 null 或者不是 Person 的一个对象,第一段代码不会做任何事情,第二段代码将会报错 。
5、assert
//确保这个变量不为空值.
assert(text != null);
//确保这个变量小于100.
assert(number < 100);
//确保它是一个https协议类型的URL.
assert(urlString.startsWith(‘https’));
提示:Assert语句仅仅只能在调试模式下使用,在生产模式下没有任何作用。
6、try { } on 异常类型 {} catch {} finally{}
try {
breedMoreLlamas();
} on OutOfLlamasException {
// 一个具体异常
buyMoreLlamas();
} on Exception catch (e) {
// 任意一个异常
print('Unknown exception: $e');
} catch (e) {
// 非具体类型
print('Something really unknown: $e');
}
像上面展示的代码一样,你可以用 on
或者 catch
,或者两者都用。当你需要指定异常类型的时候用on
,当你的异常处理者需要异常对象时用catch
。
为了确保不论是否抛出异常,代码都正常运行,请使用 finally
子句。如果没有 catch
匹配子句的异常, finally
子句运行以后异常将被传播:
try {
breedMoreLlamas();
} finally {
// 即使抛出一个异常时也会进行清理
cleanLlamaStalls();
}
在匹配了所有 catch
之后,子句 finally
运行了。
try {
breedMoreLlamas();
} catch(e) {
print('Error: $e'); // 先处理异常
} finally {
cleanLlamaStalls(); // 然后清理
}
7、
Dart 是一种面向对象语言,包含类和基于 mixin 的继承两部分。每个对象是一个类的实例,并且 Object 是所有类的父类。基于 mixin 的继承指的是每个类(除了 Object )都只有一个父类,类体还可以在多个类继承中被重用。
要创建一个对象,你可以使用 new
关键词并在其后跟上一个构造函数。构造函数可以写成类名
,或者类名.标识符
形式。
实例变量
这里是你如何声明实例变量:
class Point {
num x; // 声明实例变量 x ,默认值为 null 。
num y; // 声明实例变量 y ,默认值为 null 。
num z = 0; // 声明实例变量 z ,初始化为 0 。
}
所有未初始化的实例变量的值为 null
。
所有的实例变量会自动生成一个隐式的 getter 方法。 Non-final 实例变量也会自动生成一个隐式的 setter 方法。
8、默认构造函数
如果你不声明一个构造函数,系统会提供默认构造函数。默认构造函数没有参数,它将调用父类的无参数构造函数。
构造函数不能继承
子类不继承父类的构造函数。子类只有默认构造函数。(无参数,没有名字的构造函数)。
命名构造函数
使用命名构造函数可以为一个类声明多个构造函
class Point {
num x;
num y;
Point(this.x, this.y);
// 命名构造函数
Point.fromJson(Map json) {
x = json['x'];
y = json['y'];
}
}
数,或者说是提供额外的声明
记住,构造函数不能继承,这意味着子类不会继承父类的构造函数。如果你希望子类在创建之后能够拥有在父类中声明的命名构造函数,你就必须在子类中实现该构造函数。
9、调用非默认的父类的构造函数
默认情况下,在子类的构造函数将会调用父类的无参数构造函数。如果父类没有构造函数,则必须手动调用父类的构造函数中的一个。在冒号(:)之后、构造函数之前指定父类的构造函数(如果有的话)。
class Person {
Person.fromJson(Map data) {
print('in Person');
}
}
class Employee extends Person {
// Person 没有默认构造函数;
// 你必须调用 super.fromJson(data).
Employee.fromJson(Map data) : super.fromJson(data) {
print('in Employee');
}
}
main() {
var emp = new Employee.fromJson({});
// Prints:
// in Person
// in Employee
}
在调用父类构造函数前会检测参数,这个参数可以是一个表达式,如函数调用:
class Employee extends Person {
// ...
Employee() : super.fromJson(findDefaultData());
}
警告:父类构造函数的参数不能访问 this
。例如,参数可调用静态方法但是不能调用实方法。
初始化列表
除了调用父类构造函数,你也可以在构造函数体运行之前初始化实例变量。用逗号隔开使其分别初始化。
class Point {
num x;
num y;
Point(this.x, this.y);
// 初始化列表在构造函数运行前设置实例变量。
Point.fromJson(Map jsonMap)
: x = jsonMap['x'],
y = jsonMap['y'] {
print('In Point.fromJson(): ($x, $y)');
}
}
警告:右手边的初始化程序无法访问 this
关键字。
静态构造函数
如果你的类产生的对象永远不会改变,你可以让这些对象成为编译时常量。为此,需要定义一个 const
构造函数并确保所有的实例变量都是 final
的。
class ImmutablePoint {
final num x;
final num y;
const ImmutablePoint(this.x, this.y);
static final ImmutablePoint origin =
const ImmutablePoint(0, 0);
}
工厂构造函数
当实现一个使用 factory
关键词修饰的构造函数时,这个构造函数不必创建类的新实例。例如,工厂构造函数可能从缓存返回实例,或者它可能返回子类型的实例。 下面的示例演示一个工厂构造函数从缓存返回的对象:
class Logger {
final String name;
bool mute = false;
// _cache 是一个私有库,幸好名字前有个 _ 。
static final Map<String, Logger> _cache =
<String, Logger>{};
factory Logger(String name) {
if (_cache.containsKey(name)) {
return _cache[name];
} else {
final logger = new Logger._internal(name);
_cache[name] = logger;
return logger;
}
}
Logger._internal(this.name);
void log(String msg) {
if (!mute) {
print(msg);
}
}
}
注:工厂构造函数不能用 this。
调用一个工厂构造函数,你需要使用 new
关键字:
var logger = new Logger('UI');
logger.log('Button clicked');
10、方法
方法就是为对象提供行为的函数。
你可以使用 @override
注释来表明你重写了一个成员。
class A {
@override
void noSuchMethod(Invocation mirror) {
// ...
}
}
如果你用 noSuchMethod()
实现每一个可能的 getter 方法,setter 方法和类的方法,那么你可以使用 @proxy
标注来避免警告。