Dart Tips

DartPad

DartPad的出现让人眼前一亮,以后可以随时随地开心的测试一些代码了,Dart的大部分语言功能DartPad都支持。打开DartPad

变量初始化

如果一个对象的引用不局限于单一的类型,可以根据设计指南将其指定为Objectdynamic类型:

dynamic name1 = 'Jack';
Object name2 = 'Rose';

如果一个对象限于单一的类型:

var name1 = 'Jack';
String name2 = 'Rose';

局部变量声明的best practice是使用var来做类型被推断而非使用指定的类型。这样使用可以和其他大部分语言保持一致,提高可读性。

扩展操作符 ......?

将一个 List 中的所有元素插入到另一个 List 中:

var list1 = [1, 2, 3];
var list2 = [0, ...list1];
assert(list2.length == 4);

如果扩展操作符右边可能为null:

var list1;
var list2 = [0, ...?list1];
assert(list2.length == 1);

集合中使用控制流

使用Collection If来创建一个List:

var animals = [
  'Dog',
  'Cat',
  'Fish',
  if (canFly) 'Bird'
];

使用Collection For将列表中的元素修改后添加到另一个列表中:

var listOfInts = [1, 2, 3];
var listOfStrings = [
  0,
  for (var i in listOfInts) i*i
];
print(listOfStrings); // [0, 1, 4, 9]

常量声明 final 和 const

  • const是编译时常量,final是运行时常量。二者都只能被赋值一次。
  • 实例变量可以是final的但不可以是const的,final实例变量必须在构造器开始前被初始化,比如在声明实例变量时初始化,或者作为构造器参数,或者将其置于构造器的初始化列表中。
  • 如果使用const修饰类中的变量,则必须加上static关键字,即static const
  • 没有使用finalconst修饰的变量的值是可以被更改的,即使这些变量之前引用过const的值。
var list = const [];
list = [1, 2, 3];
  • Dart2.5之后可以在定义常量时使用isas......?collection ifcollection for
const Object i = 3;
const list = [i as int];
const map = {if (i is int) i: "int"};
const set = {if (list is List<int>) ...list};

可选参数

  • 命名参数:使用{param1, param2, …}的形式来指定命名参数。调用时需要指定对应的命名,也可以使用@required来标识一个命名参数是必须的参数。使用@required需要导入package:meta/meta.dart
  void setUserInfo(String name, {@required int age, double height = 0, double weight = 0}) {
    print('My name is $name, I am $age years old.');
    if (height > 0) { print('My height is $height'); }
    if (weight > 0) { print('My weight is $weight'); }
    print('\n');
  }
  setUserInfo('Jack', age: 18);
  setUserInfo('Rose', age: 18, height: 170);
My name is Jack, I am 18 years old.

My name is Rose, I am 18 years old.
My height is 170
  • 位置参数:使用[param1, param2, …]的形式来指定位置参数。调用时需将位置对应起来。
  void setUserInfo(String name, [int age, double height = 0, double weight = 0]) {
    print('My name is $name, I am $age years old.');
    if (height > 0) { print('My height is $height'); }
    if (weight > 0) { print('My weight is $weight'); }
    print('\n');
  }
  setUserInfo('Jack', 18);
  setUserInfo('Rose', 18, 170, 105);
My name is Jack, I am 18 years old.

My name is Rose, I am 18 years old.
My height is 170
My weight is 105

级联调用

..级联操作并非一个运算符而是Dart的特殊语法。

querySelector('#confirm') // 获取对象
  ..text = 'Confirm' // 使用对象的成员
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));

querySelector返回了一个Selector对象,后面的级联操作符都是调用这个Selector对象的成员并忽略每个操作的返回值。上面的代码等价于:

var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));

在返回对象的函数中谨慎使用级联操作符:

var sb = StringBuffer();
sb.write('foo')
  ..write('bar'); // (Error: method 'write' isn't defined for 'void').

上述代码中的 sb.write() 方法返回的是 void,返回值为 void 的方法则不能使用级联运算符。

Getter 和 Setter

所有实例变量均会隐式地声明一个Getter方法,非final类型的实例变量还会隐式地声明一个Setter方法。可以使用getset关键字为额外的属性添加GetterSetter方法:

class Rectangle {
  num left, top, width, height;
  Rectangle(this.left, this.top, this.width, this.height);
  // 定义两个计算产生的属性:right 和 bottom。
  num get right => left + width;
  set right(num value) => left = value - width;
  num get bottom => top + height;
  set bottom(num value) => top = value - height;
}
void main() {
  var rect = Rectangle(3, 4, 20, 15);
  assert(rect.left == 3);
  rect.right = 12;
  assert(rect.left == -8);
}

使用 Getter 和 Setter 的好处是,你可以先使用你的实例变量,过一段时间过再将它们包裹成方法且不需要改动任何代码,即先定义后更改且不影响原有逻辑。

类中的关键字

  • abstract可以让该类成为抽象类,抽象类将无法被实例化,常用于声明接口方法。
abstract class Animal {
  void eat(); // 抽象方法。
}
class Dog extends Animal {
  void eat() {
    print('Dog eat!'); 
  }
}
  • implements为隐式接口,每一个类都隐式地定义了一个接口并实现了该接口,这个接口包含所有这个类的实例成员以及这个类所实现的其它接口。如果想要创建一个A类支持调用B类的API且不想继承B类,则可以实现B类的接口。
class Point implements Comparable, Location {...}
  • extends关键字创建一个子类,可使用super关键字引用一个父类,可以使用@override重写父类的实例方法。
class Television {
  void turnOn() {
  }
}
class SmartTelevision extends Television {
  void turnOn() {
    super.turnOn();
  }
}
class SmartTelevision extends Television {
  @override
  void turnOn() {
  }
}
  • Mixin是一种在多重继承中复用某个类中代码的方法模式。使用with关键字在其后跟上Mixin类的名字来使用Mixin模式。Mixin类继承自Object并且不为该类定义构造函数,可以使用关键字on来指定哪些类可以使用该Mixin类。
class Musician extends Performer with Musical {
}
class Maestro extends Person with Musical, Aggressive, Demented {
}
mixin MusicalPerformer on Musician {
}

库和可见性

  • as用来指定前缀解决两个代码库有冲突的情况。比如如果library1library2都有Element类:
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// 使用 lib1 的 Element 类。
Element element1 = Element();
// 使用 lib2 的 Element 类。
lib2.Element element2 = lib2.Element();
  • showhide可以有选择地导入代码库:
// 只导入 lib1 中的 foo。(Import only foo).
import 'package:lib1/lib1.dart' show foo;
// 导入 lib2 中除了 foo 外的所有。
import 'package:lib2/lib2.dart' hide foo;
  • deferred as来标识需要延时加载的代码库:
import 'package:greetings/hello.dart' deferred as hello;

当实际需要使用到库中API时先调用loadLibrary函数加载库:

Future greet() async {
  await hello.loadLibrary();
  hello.printGreeting();
}

未完待续

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容