为了使文件前面部分保持整洁,咱们规定了关键字出现顺序的规则。每一个“部分”应该使用空行分割。html
要把 “dart:” 导入语句放到其余导入语句以前。编程
要把 “package:” 导入语句放到项目相关导入语句以前。bash
import 'dart:async';
import 'dart:html';
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'util.dart';
复制代码
推荐 把外部扩展 “package:” 导入语句放到其余语句以前。async
若是你使用了多个 “package:” 导入语句来导入本身的包以及其余外部扩展包,推荐将本身的包分开放到一个额外的部分。函数式编程
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'package:my_package/util.dart';
复制代码
要 把导出(export)语句做为一个单独的部分放到全部导入语句以后。函数
import 'src/error.dart';
import 'src/foo_bar.dart';
export 'src/error.dart';
复制代码
在 Dart 中,未初始化的变量拥有一个默认的初始化值:null。即使数字也是如此,由于在 Dart 中一切皆为对象,数字也不例外。ui
int lineCount;
assert(lineCount == null);
复制代码
在Dart中用var声明一个变量后,Dart在编译时会根据第一次赋值数据的类型来推断其类型,编译结束后其类型就已经被肯定。atom
Object 是Dart全部对象的根基类,也就是说全部类型都是Object的子类(包括Function和Null),因此任何类型的数据均可以赋值给Object声明的对象. dynamic与var同样都是关键词,声明的变量能够赋值任意对象。 而dynamic与Object相同之处在于,他们声明的变量能够在后期改变赋值类型。spa
dynamic t;
Object x;
t = "hi world";
x = 'Hello Object';
//下面代码没有问题
t = 1000;
x = 1000;
复制代码
dynamic与Object不一样的是,dynamic声明的对象编译器会提供全部可能的组合, 而Object声明的对象只能使用Object的属性与方法, 不然编译器会报错。代码规范
dynamic的这个特性与Objective-C中的id做用很像. dynamic的这个特色使得咱们在使用它时须要格外注意,这很容易引入一个运行时错误.
若是您从未打算更改一个变量,那么使用 final 或 const,不是var,也不是一个类型。 一个 final 变量只能被设置一次,二者区别在于:const 变量是一个编译时常量,final变量在第一次使用时被初始化。被final或者const修饰的变量,变量类型能够省略,如:
//能够省略String这个类型声明
final str = "hi world";
//final String str = "hi world";
const str1 = "hi world";
//const String str1 = "hi world";
复制代码
Dart是一种真正的面向对象的语言,因此即便是函数也是对象,而且有一个类型Function。这意味着函数能够赋值给变量或做为参数传递给其余函数,这是函数式编程的典型特征。
Dart函数声明若是没有显式声明返回值类型时会默认当作dynamic处理,注意,函数返回值没有类型推断。
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
typedef bool CALLBACK();
//不指定返回类型,此时默认为dynamic,不是bool
isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
void test(CALLBACK cb){
print(cb());
}
//报错,isNoble不是bool类型
test(isNoble);
复制代码
级联运算符(..)可让你在同一个对象上连续调用多个对象的变量或方法。
好比下面的代码:
querySelector('#confirm') // 获取对象 (Get an object).
..text = 'Confirm' // 使用对象的成员 (Use its members).
..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.lis
复制代码
ten((e) => window.alert('Confirmed!')); 级联运算符能够嵌套,例如:
final addressBook = (AddressBookBuilder()
..name = 'jenny'
..email = 'jenny@example.com'
..phone = (PhoneNumberBuilder()
..number = '415-555-0100'
..label = 'home')
.build())
.build();
复制代码
使用类的成员 对象的 成员 由函数和数据(即 方法 和 实例变量)组成。方法的 调用 要经过对象来完成,这种方式能够访问对象的函数和数据。
使用(.)来访问对象的实例变量或方法:
var p = Point(2, 2);
// 为实例变量 y 赋值。
p.y = 3;
// 获取 y 的值。
assert(p.y == 3);
// 调用变量 p 的 distanceTo() 方法。
num distance = p.distanceTo(Point(4, 4));
复制代码
使用 ?. 代替 . 能够避免由于左边表达式为 null 而致使的问题:
// If p is non-null, set its y value to 4.
// 若是 p 为非空则将其属性 y 的值设为 4
p?.y = 4;
复制代码
使用构造函数 可使用 构造函数 来建立一个对象。构造函数的命名方式能够为 类名 或 类名.标识符 的形式。例以下述代码分别使用 Point() 和 Point.fromJson() 两种构造器建立了 Point 对象:
var p1 = Point(2, 2);
var p2 = Point.fromJson({'x': 1, 'y': 2});
复制代码
如下代码具备相同的效果,可是构造函数名前面的的 new 关键字是可选的:
var p1 = new Point(2, 2);
var p2 = new Point.fromJson({'x': 1, 'y': 2});
复制代码
从 Dart 2 开始,new 关键字是可选的。
复制代码
获取对象的类型 可使用 Object 对象的 runtimeType 属性在运行时获取一个对象的类型,该对象类型是 Type 的实例。
print('The type of a is ${a.runtimeType}');
复制代码