2019-03-19 _Dart 2.2.1
首先Dart網(wǎng)站的重要的概念應(yīng)該看一下:
在學(xué)習(xí) Dart 的時候抠藕,請牢記下面一些事實和概念:
- 所有能夠使用變量引用的都是對象, 每個對象都是一個類的實例蒋困。在 Dart 中 甚至連 數(shù)字盾似、方法和
null
都是對象。所有的對象都繼承于 Object 類雪标。 - 使用靜態(tài)類型(例如前面示例中的
num
) 可以更清晰的表明你的意圖零院,并且可以讓靜態(tài)分析工具來分析你的代碼, 但這并不是牽制性的村刨。(在調(diào)試代碼的時候你可能注意到 沒有指定類型的變量的類型為dynamic
告抄。) - Dart 在運行之前會先解析你的代碼。你可以通過使用 類型或者編譯時常量來幫助 Dart 去捕獲異常以及 讓代碼運行的更高效嵌牺。
- Dart 支持頂級方法 (例如
main()
)打洼,同時還支持在類中定義函數(shù)。 (靜態(tài)函數(shù)和實例函數(shù))逆粹。 你還可以在方法中定義方法 (嵌套方法或者局部方法)募疮。 - 同樣,Dart 還支持頂級變量僻弹,以及 在類中定義變量(靜態(tài)變量和實例變量)阿浓。 實例變量有時候被稱之為域(Fields)或者屬性(Properties)。
- 和 Java 不同的是蹋绽,Dart 沒有
public
芭毙、protected
、 和private
關(guān)鍵字卸耘。如果一個標(biāo)識符以 (_) 開頭退敦,則該標(biāo)識符 在庫內(nèi)是私有的。詳情請參考: 庫和可見性蚣抗。 - 標(biāo)識符可以以字母或者 _ 下劃線開頭苛聘,后面可以是 其他字符和數(shù)字的組合。
- 有時候 表達式 expression 和 語句 statement 是有區(qū)別的忠聚,所以這種情況我們會分別指明每種情況设哗。
- Dart 工具可以指出兩種問題:警告和錯誤。 警告只是說你的代碼可能有問題两蟀, 但是并不會阻止你的代碼執(zhí)行网梢。 錯誤可以是編譯時錯誤也可以是運行時錯誤。遇到編譯時錯誤時赂毯,代碼將 無法執(zhí)行战虏;運行時錯誤將會在運行代碼的時候?qū)е乱粋€ 異常。
變量
- 可以使用 var 聲明變量( java 10也可以 )
var a = 10;
- 另外對于動態(tài)類型 Dart 還有
dynamic
關(guān)鍵字 - Dart 所有變量如果未初始化都為
null
,不像 javaint
的默認值是 0,boolean
的默認值是 false -
final
表示不可變党涕,const
表示常量烦感,static
表示的意義相同都是可以直接通過類名的方式使用方法和屬性
內(nèi)建類型
- 沒有
float
類型,int
和double
都是num
的子類 -
String
字符串內(nèi)部可以使用表達式${}
膛堤,(和kotlin
的使用方式一致),使用單引號和雙引號包圍手趣,使用三個單引號或雙引號包圍的字符可以換行,支持emoji表情
var s = 'string interpolation';
var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
var s4 = "That deserves all caps. ${s.toUpperCase()} is very handy!";
var s5 = '''
You can create
multi-line strings like this one.
''';
var s6 = """This is also a
multi-line string.""";
var clapping = '\u{1f44f}'; //??
- 沒有數(shù)組只有列表肥荔,List, Set, Map 不是抽象接口绿渣,可以直接使用,并且支持泛形
var list = [1, 2, 3]; // 列表
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'}; // Set
var gifts = {
// Key: Value
'first': 'partridge',
'second': 'turtledoves',
'fifth': 'golden rings'
}; // Map
方法
- 支持頂級方法燕耿,方法也是對象中符, 支持
lambda
表達式的寫法 - 如果方法的參數(shù)是解構(gòu)出來的可以通過
@required
注解標(biāo)注為必填const Scrollbar({Key key, @required Widget child})
- 支持可選參數(shù),可選參數(shù)寫在最后并且使用
[]
包圍String say(String from, String msg, [String device])
- 支持默認參數(shù)
void enableFlags({bool bold = false, bool hidden = false}) {...}
- 支持匿名方法
(參數(shù)){方法體}
var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
print('${list.indexOf(item)}: $item');
});
- 支持閉包
Function makeAdder(num addBy) {
return (num i) => addBy + i;
}
void main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
操作符
-
as , is, is!
:as
類似與強制類型轉(zhuǎn)換誉帅,is
類似instanceof
- 空替換
??
:String playerName(String name) => name ?? 'Guest';
等價于String playerName(String name) => name != null ? name : 'Guest';
- 級聯(lián)符號 (..) 可以代替構(gòu)建者模式
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
// 使用級聯(lián)操作
querySelector('#confirm') // Get an object.
..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
-
?.
操作符當(dāng)對象不為空時調(diào)用后面的屬性或方法:foo?.a
類似于if( foo != null) f.a;
異常
- Dart的異常是不用必須捕獲的
-
try {} catch
有點不一樣
try {
breedMoreLlamas();
} on OutOfLlamasException {
// 只捕獲 OutOfLlamasException
buyMoreLlamas();
} on Exception catch (e) {
// 上面不能捕獲的且是Exception的子類
print('Unknown exception: $e');
} catch (e,s) {
// 其余的所有異常淀散,s ==》 stack trace
print('Something really unknown: $e');
rethrow; //不處理,直接拋出去
}
類
- 創(chuàng)建對象可以不使用
new
關(guān)鍵字 - 可以給構(gòu)造方法命名
class Point {
num x, y;
Point(this.x, this.y);
// Named constructor
Point.origin() {
x = 0;
y = 0;
}
}
- 調(diào)用父類的構(gòu)造方法(
:
)
class Person {
String firstName;
Person.fromJson(Map data) {
print('in Person');
}
}
class Employee extends Person {
// Person does not have a default constructor;
// you must call super.fromJson(data).
Employee.fromJson(Map data) : super.fromJson(data) {
print('in Employee');
}
}
- 在構(gòu)造方法的方法體調(diào)用之前初始化屬性
import 'dart:math';
class Point {
final num x;
final num y;
final num distanceFromOrigin;
Point(x, y)
: x = x,
y = y,
distanceFromOrigin = sqrt(x * x + y * y);
}
- 常量構(gòu)造方法蚜锨,在構(gòu)造方法之前使用
const
修飾档插,屬性必需是final
或者const
的
class ImmutablePoint {
static final ImmutablePoint origin =
const ImmutablePoint(0, 0);
final num x, y;
const ImmutablePoint(this.x, this.y);
}
const ca = ImmutablePoint(1,1); // const 修飾的變量 必須是const的構(gòu)造方法
var a = const ImmutablePoint(1, 1);
var b = const ImmutablePoint(1, 1);
assert(identical(a, b)); // true
-
factory
修飾的構(gòu)造方法為工廠方法
class Logger {
final String name;
bool mute = false;
// _cache is library-private, thanks to
// the _ in front of its name.
static final Map<String, Logger> _cache =
<String, Logger>{};
factory Logger(String name) {
if (_cache.containsKey(name)) {
return _cache[name];
} else {
final logger = Logger._internal(name);
_cache[name] = logger;
return logger;
}
}
Logger._internal(this.name);
void log(String msg) {
if (!mute) print(msg);
}
}
-
runtimeType
關(guān)鍵字 獲取變量運行時的類型print('The type of a is ${a.runtimeType}');
Dart 的泛形是不擦除的 -
getter
和setter
: 通過這兩個關(guān)鍵字可以自定義屬性的值
class Rectangle {
num left, top, width, height;
Rectangle(this.left, this.top, this.width, this.height);
// Define two calculated properties: right and 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;
}
- 沒有
interfaces
關(guān)鍵字,每個類都是一個接口 -
支持操作符重載
操作符 - 支持重寫
noSuchMethod()
方法,當(dāng)對象調(diào)用不存在的屬性或方法時該方法會被調(diào)用 - 支持混入
mixin
, 提供by, mixin, mixin ..on
關(guān)鍵字
泛形
- Java 運行時會擦除泛形,Dart 不會
var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
print(names is List<String>); // true
庫和可見性
- Dart 使用 URI 來確定一個庫, 可以給庫添加前綴(使用
as
關(guān)鍵詞)
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// Uses Element from lib1.
Element element1 = Element();
// Uses Element from lib2.
lib2.Element element2 = lib2.Element();
- 支持導(dǎo)入部分庫(
show
),或者隱藏部分庫(hide
)
// Import only foo.
import 'package:lib1/lib1.dart' show foo;
// Import all names EXCEPT foo.
import 'package:lib2/lib2.dart' hide foo;
- 支持懶加載
deferred as
import 'package:greetings/hello.dart' deferred as hello;
Future greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
異步
-
async, await
關(guān)鍵字, 聲明耗時操作,返回值必須是Future
方法名后用async
標(biāo)注, 調(diào)用耗時操作時需要使用await
關(guān)鍵字,并且在async
標(biāo)注的方法中
Future<String> lookUpVersion() async => '1.0.0';
Future checkVersion() async {
var version = await lookUpVersion();
// Do something with version
}
-
Stream
關(guān)鍵字使用await for
或者listen
方法
Future main() async {
// ...
await for (var request in requestServer) {
handleRequest(request);
}
// ...
}
生成器
// 同步
Iterable<int> naturalsTo(int n) sync* {
int k = 0;
while (k < n) yield k++;
}
// 異步
Stream<int> asynchronousNaturalsTo(int n) async* {
int k = 0;
while (k < n) yield k++;
}
// 返回值為遞歸
Iterable<int> naturalsDownFrom(int n) sync* {
if (n > 0) {
yield n;
yield* naturalsDownFrom(n - 1);
}
}
可運行的類
- 如果類中實現(xiàn)了
call
方法, 那么這個類就是可執(zhí)行的
class WannabeFunction {
call(String a, String b, String c) => '$a $b $c!';
}
main() {
var wf = new WannabeFunction();
var out = wf("Hi","there,","gang");
print('$out');
}
Typedefs
- 使用
typedef
關(guān)鍵字 標(biāo)注方法簽名,可以避免方法簽名的丟失
typedef Compare = int Function(Object a, Object b);
class SortedCollection {
Compare compare;
SortedCollection(this.compare);
}
// Initial, broken implementation.
int sort(Object a, Object b) => 0;
void main() {
SortedCollection coll = SortedCollection(sort);
assert(coll.compare is Function);
assert(coll.compare is Compare);
}
注解
- Dart 使用類來聲明注解, Java 使用
@interface
; 另外 Dart 貌似沒有地方聲明注解的使用范圍
注釋
- Dart 可以使用
///, /**
編寫文檔注釋