“本文主要介紹Dart 基礎知識筆記。
”
main() 函數是 Dart 程序的入口main() 函數返回 void 并具有可選的 List<String> 參數作為參數Object 類(lèi)繼承dynamicvar name = 'Bob'; 這里的 name 類(lèi)型推斷為 Stringnull,包括數字類(lèi)型Runesvar s = r'In a raw stringList 對象var halogens = {'fluorine', 'chlorine'}{} 默認為 Map 類(lèi)型,var names = {}; 創(chuàng )建了 Map 而不是 Setnew 關(guān)鍵字是可選的 (Dart 2開(kāi)始)Function,可以將函數分配給變量或作為參數傳遞給其他函數=> expr 用于簡(jiǎn)化僅包含一個(gè)表達式的函數= 來(lái)定義命名參數和位置參數的默認值。默認值必須是編譯時(shí)常量~/ 返回除法的整數結果switch 語(yǔ)句使用 == 比較整數、字符串、枚舉或編譯時(shí)常量Exception 和 Error 類(lèi)型,并且支持將任何非 null 對象作為異常拋出runtimeType 屬性返回對象類(lèi)型async/await 關(guān)鍵字處理 Future 結果await for 處理 Stream 結果// 延遲導入庫
import 'package:greetings/hello.dart' deferred as hello;
// 使用庫
Future greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
開(kāi)發(fā)過(guò)程中可以使用 assert(condition , optionalMessage) 斷言,檢查某些條件是否為真。斷言通常由工具或框架決定是否生效:
--enable-asserts 標志啟用斷言Dart 中的構造函數跟 Java 中的構造函數還是有不小的區別,所以值得獨立作為一節來(lái)討論。
這里先列出了 Dart 構造函數相關(guān)的一些術(shù)語(yǔ)。
如果你清楚這些術(shù)語(yǔ),說(shuō)明你已經(jīng)基本掌握了 Dart 構造函數,完全可以略過(guò)本節。如果不清楚,不妨往下看。
Dart 中通過(guò)創(chuàng )建一個(gè)與其類(lèi)具有相同名稱(chēng)的函數來(lái)聲明一個(gè)構造函數??梢院芊奖愕貙嬙旌瘮祬蒂x值給實(shí)例變量:
class Point {
num x, y;
// Syntactic sugar for setting x and y
// before the constructor body runs.
Point(this.x, this.y);
}
Dart 中使用命名構造函數可為一個(gè)類(lèi)實(shí)現多個(gè)構造函數或提供額外的清晰度:
class Point {
num x, y;
Point(this.x, this.y);
// Named constructor
Point.origin() {
x = 0;
y = 0;
}
}
構建函數的執行順序如下:
注意:如果超類(lèi)沒(méi)有未命名,無(wú)參數的構造函數,則必須手動(dòng)調用超類(lèi)中的構造函數之一
class Employee extends Person {
Employee() : super.fromJson(getDefaultData());
// ···
}
在實(shí)現并非總是創(chuàng )建其類(lèi)的新實(shí)例的構造函數時(shí),要使用 factory 關(guān)鍵字。示例如下:
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) {
return _cache.putIfAbsent(
name, () => Logger._internal(name));
}
Logger._internal(this.name);
void log(String msg) {
if (!mute) print(msg);
}
}
每個(gè)類(lèi)都隱式定義一個(gè)接口。
// A person. The implicit interface contains greet().
class Person {
// In the interface, but visible only in this library.
final _name;
// Not in the interface, since this is a constructor.
Person(this._name);
// In the interface.
String greet(String who) => 'Hello, $who. I am $_name.';
}
// An implementation of the Person interface.
class Impostor implements Person {
get _name => '';
String greet(String who) => 'Hi $who. Do you know who I am?';
}
Mixins是在多個(gè)類(lèi)層次結構中重用類(lèi)代碼的一種方式。
首先看如何實(shí)現 mixin。使用 mixin 關(guān)鍵字創(chuàng )建一個(gè)擴展自 Object 且不聲明構造函數的類(lèi)。還可以使用 on 關(guān)鍵字來(lái)限定可以使用該 mixin 的類(lèi)
mixin Musical {
bool canPlayPiano = false;
bool canCompose = false;
bool canConduct = false;
void entertainMe() {
if (canPlayPiano) {
print('Playing piano');
} else if (canConduct) {
print('Waving hands');
} else {
print('Humming to self');
}
}
}
mixin MusicalPerformer on Musician {
// ···
}
再來(lái)看如何使用 mixin
從設計者角度來(lái)說(shuō)是一些錦上添花的語(yǔ)言特性,但從開(kāi)發(fā)者角度來(lái)確實(shí)很方便。
類(lèi)型推斷
num highScore(List<num> scores) {
var highest = 0;
for (var score in scores) {
if (score > highest) highest = score;
}
return highest;
}
擴展操作符 ...
var list = [1, 2, 3];
var list2 = [0, ...list];
assert(list2.length == 4);
nullable 擴展操作符 ...?
var list;
var list2 = [0, ...?list];
assert(list2.length == 1);
命名參數 (Named parameters) paramName : value
// 定義命名參數
/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool bold, bool hidden}) {...}
// 指定命名參數
enableFlags(bold: true, hidden: false);
位置參數 (Positional parameters)
// 使用[]標記一組可選的位置參數
String say(String from, String msg, [String device]) {
...
}
級聯(lián)操作符 ..。這個(gè)操作符可以節省創(chuàng )建臨時(shí)變量的步驟。
void main() {
querySelector('#sample_text_id')
..text = 'Click me!'
..onClick.listen(reverseText);
}
匿名函數
var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
print('${list.indexOf(item)}: $item');
});
??= 操作符。這個(gè)操作符讓代碼更簡(jiǎn)潔
// Assign value to b if b is null; otherwise, b stays the same
b ??= value;
?? 操作符。這個(gè)操作符讓代碼更簡(jiǎn)潔
// 如果 name 為 null 則返回 'Guest'
String playerName(String name) => name ?? 'Guest';
?. 操作符,表示有條件的成員訪(fǎng)問(wèn),最左邊的操作數可以為 null
typedef 用于給函數類(lèi)型提供一個(gè)名稱(chēng)
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);
}
operator 來(lái)重載操作符call() 方法的類(lèi),可以像調用函數一樣調用該類(lèi)的實(shí)例https://renato.athaydes.com/posts/interesting-dart-features.html#quick-dart-overview
聯(lián)系客服