Dart 關(guān)鍵字【2】

想要寫好Flutter,那么對(duì)Dart的基本關(guān)鍵字的掌握是必不可少的杠巡,今天就再探究一下其他的關(guān)鍵字。

as is si!

as is is!,運(yùn)算符用于運(yùn)行時(shí)處理類型檢查:

當(dāng)obj實(shí)現(xiàn)了T的接口時(shí),obj is Ttrue,obj as T可以將obj類型轉(zhuǎn)換成T類型:


class Person {
  void play(){
    print('person');
  }
}
class PersonSub extends Person{}
class Person2 {
    void play(){
    print('person2');
  }
}

 Person person = PersonSub();
 if(person is Person2){
 (person as Person2).play();
 }
 if(person is PersonSub){
   (person as PersonSub).play();
 }

當(dāng)person類型是Person2執(zhí)行第一個(gè)if函數(shù),如果直接(person as Person2).play();卧晓,則會(huì)崩潰,每次轉(zhuǎn)換類型的時(shí)候赴捞,提交校驗(yàn)a is T是有必要的逼裆。

enum

枚舉類型也稱為 enumerationsenums , 是一種特殊的類赦政,用于表示數(shù)量固定的常量值胜宇。

throw catch on final rethrow

捕獲異常可以避免異常繼續(xù)傳遞(除非重新拋出(rethrow )異常)恢着。 可以通過(guò)捕獲異常的機(jī)會(huì)來(lái)處理該異常:

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  buyMoreLlamas();
}

通過(guò)指定多個(gè) catch 語(yǔ)句桐愉,可以處理可能拋出多種類型異常的代碼。 與拋出異常類型匹配的第一個(gè) catch 語(yǔ)句處理異常掰派。 如果 catch 語(yǔ)句未指定類型从诲, 則該語(yǔ)句可以處理任何類型的拋出對(duì)象:

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // 一個(gè)特殊的異常
  buyMoreLlamas();
} on Exception catch (e) {
  // 其他任何異常
  print('Unknown exception: $e');
} catch (e) {
  // 沒(méi)有指定的類型,處理所有異常
  print('Something really unknown: $e');
}

如上述代碼所示靡羡,捕獲語(yǔ)句中可以同時(shí)使用 oncatch 系洛,也可以單獨(dú)分開(kāi)使用。 使用 on 來(lái)指定異常類型略步, 使用 catch 來(lái) 捕獲異常對(duì)象描扯。

catch() 函數(shù)可以指定1到2個(gè)參數(shù), 第一個(gè)參數(shù)為拋出的異常對(duì)象趟薄, 第二個(gè)為堆棧信息 ( 一個(gè) StackTrace 對(duì)象 )荆烈。

try {
  // ···
} on Exception catch (e) {
  print('Exception details:\n $e');
} catch (e, s) {
  print('Exception details:\n $e');
  print('Stack trace:\n $s');
}

如果僅需要部分處理異常, 那么可以使用關(guān)鍵字 rethrow 將異常重新拋出竟趾。

void misbehave() {
  try {
    dynamic foo = true;
    print(foo++); // Runtime error
  } catch (e) {
    print('misbehave() partially handled ${e.runtimeType}.');
    rethrow; // Allow callers to see the exception.
  }
}

void main() {
  try {
    misbehave();
  } catch (e) {
    print('main() finished handling ${e.runtimeType}.');
  }
}

不管是否拋出異常憔购,finally 中的代碼都會(huì)被執(zhí)行。 如果 catch 沒(méi)有匹配到異常岔帽, 異常會(huì)在 finally 執(zhí)行完成后玫鸟,再次被拋出:

try {
  breedMoreLlamas();
} finally {
  // Always clean up, even if an exception is thrown.
  cleanLlamaStalls();
}

任何匹配的 catch 執(zhí)行完成后,再執(zhí)行 finally

try {
  breedMoreLlamas();
} catch (e) {
  print('Error: $e'); // Handle the exception first.
} finally {
  cleanLlamaStalls(); // Then clean up.
}

factory

當(dāng)執(zhí)行構(gòu)造函數(shù)并不總是創(chuàng)建這個(gè)類的一個(gè)新實(shí)例時(shí)犀勒,則使用 factory 關(guān)鍵字屎飘。 例如妥曲,一個(gè)工廠構(gòu)造函數(shù)可能會(huì)返回一個(gè) cache 中的實(shí)例, 或者可能返回一個(gè)子類的實(shí)例钦购。

以下示例演示了從緩存中返回對(duì)象的工廠構(gòu)造函數(shù):

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 = Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) print(msg);
  }
}

const

使用過(guò)程中從來(lái)不會(huì)被修改的變量押桃, 可以使用 final 或 const, 而不是 var 或者其他類型葵萎, Final 變量的值只能被設(shè)置一次; Const 變量在編譯時(shí)就已經(jīng)固定 (Const 變量 是隱式 Final 的類型.) 最高級(jí) final 變量或類變量在第一次使用時(shí)被初始化唱凯。

提示: 實(shí)例變量可以是 final 類型但不能是 const 類型羡忘。 必須在構(gòu)造函數(shù)體執(zhí)行之前初始化 final 實(shí)例變量 —— 在變量聲明中,參數(shù)構(gòu)造函數(shù)中或構(gòu)造函數(shù)的初始化列表中進(jìn)行初始化磕昼。

創(chuàng)建和設(shè)置一個(gè) Final 變量:

final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';

final 不能被修改:

name = 'Alice'; // Error: 一個(gè) final 變量只能被設(shè)置一次卷雕。

如果需要在編譯時(shí)就固定變量的值,可以使用 const 類型變量票从。 如果 Const 變量是類級(jí)別的漫雕,需要標(biāo)記為 static const。 在這些地方可以使用在編譯時(shí)就已經(jīng)固定不變的值峰鄙,字面量的數(shù)字和字符串蝎亚, 固定的變量,或者是用于計(jì)算的固定數(shù)字:

const bar = 1000000; // 壓力單位 (dynes/cm2)
const double atm = 1.01325 * bar; // 標(biāo)準(zhǔn)氣壓

operator

重寫運(yùn)算符先馆,下面的運(yùn)算符可以被重寫躺彬。

< + | []
> / ^ [] =
<= ~/ & ~
>= * << ==
% >>

提示: 你可能會(huì)被提示 != 運(yùn)算符為非可重載運(yùn)算符仿野。 因?yàn)?e1 != e2 表達(dá)式僅僅是 !(e1 == e2) 的語(yǔ)法糖。

下面示例演示一個(gè)類重寫 + 和 - 操作符:

class Vector {
  final int x, y;

  Vector(this.x, this.y);

  Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
  Vector operator -(Vector v) => Vector(x - v.x, y - v.y);

  // 運(yùn)算符 == 和 hashCode 部分沒(méi)有列出。 有關(guān)詳情亿扁,請(qǐng)參考下面的注釋从祝。
  // ···
}

void main() {
  final v = Vector(2, 3);
  final w = Vector(2, 2);

  assert(v + w == Vector(4, 5));
  assert(v - w == Vector(0, 1));
}

如果要重寫 == 操作符,需要重寫對(duì)象的 hashCode getter 方法擎浴。 重寫 == 和 hashCode 的實(shí)例贮预,參考 Implementing map keys.

part part of

covariant

Function

Dart 是一門真正面向?qū)ο蟮恼Z(yǔ)言萌狂, 甚至其中的函數(shù)也是對(duì)象茫藏,并且有它的類型 Function 。 這也意味著函數(shù)可以被賦值給變量或者作為參數(shù)傳遞給其他函數(shù)。 也可以把 Dart 類的實(shí)例當(dāng)做方法來(lái)調(diào)用挟伙。 有關(guān)更多信息,參考 Callable classes.

已下是函數(shù)實(shí)現(xiàn)的示例:

bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

雖然在 Effective Dart 中推薦 公共API中聲明類型, 但是省略了類型聲明,函數(shù)依舊是可以正常使用的:

isNoble(atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

如果函數(shù)中只有一句表達(dá)式齿坷,可以使用簡(jiǎn)寫語(yǔ)法:

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
=> expr 語(yǔ)法是 { return expr; } 的簡(jiǎn)寫。 => 符號(hào) 有時(shí)也被稱為 箭頭 語(yǔ)法。

提示: 在箭頭 (=>) 和分號(hào) (;) 之間只能使用一個(gè) 表達(dá)式 蚕愤,不能是 語(yǔ)句 饺蚊。 例如:不能使用 if 語(yǔ)句 污呼,但是可以是用 條件表達(dá)式.

with

default

return yield

deferred hide

延遲加載庫(kù)
Deferred loading (也稱之為 lazy loading) 可以讓應(yīng)用在需要的時(shí)候再加載庫(kù)包竹。 下面是一些使用延遲加載庫(kù)的場(chǎng)景:

  • 減少 APP 的啟動(dòng)時(shí)間苗缩。
  • 執(zhí)行 A/B 測(cè)試彼乌,例如 嘗試各種算法的 不同實(shí)現(xiàn)灶挟。
  • 加載很少使用的功能墅垮,例如可選的屏幕和對(duì)話框。

要延遲加載一個(gè)庫(kù)剃允,需要先使用 deferred as 來(lái)導(dǎo)入:

import 'package:greetings/hello.dart' deferred as hello;

當(dāng)需要使用的時(shí)候斥废,使用庫(kù)標(biāo)識(shí)符調(diào)用 loadLibrary() 函數(shù)來(lái)加載庫(kù):

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

在一個(gè)庫(kù)上你可以多次調(diào)用 loadLibrary() 函數(shù)牡肉。但是該庫(kù)只是載入一次。

使用延遲加載庫(kù)的時(shí)候逾雄,請(qǐng)注意一下問(wèn)題:

延遲加載庫(kù)的常量在導(dǎo)入的時(shí)候是不可用的。 只有當(dāng)庫(kù)加載完畢的時(shí)候做鹰,庫(kù)中常量才可以使用击纬。
在導(dǎo)入文件的時(shí)候無(wú)法使用延遲庫(kù)中的類型。 如果你需要使用類型誊垢,則考慮把接口類型移動(dòng)到另外一個(gè)庫(kù)中掉弛, 讓兩個(gè)庫(kù)都分別導(dǎo)入這個(gè)接口庫(kù)。
Dart 隱含的把 loadLibrary() 函數(shù)導(dǎo)入到使用 deferred as 的命名空間 中喂走。 loadLibrary() 方法返回一個(gè) Future殃饿。

show hide

導(dǎo)入庫(kù)的一部分
如果你只使用庫(kù)的一部分功能,則可以選擇需要導(dǎo)入的 內(nèi)容芋肠。例如:

// Import only foo.
import 'package:lib1/lib1.dart' show foo;

// Import all names EXCEPT foo.
import 'package:lib2/lib2.dart' hide foo;

參考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末乎芳,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子帖池,更是在濱河造成了極大的恐慌奈惑,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件睡汹,死亡現(xiàn)場(chǎng)離奇詭異肴甸,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)囚巴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門原在,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人彤叉,你說(shuō)我怎么就攤上這事庶柿。” “怎么了秽浇?”我有些...
    開(kāi)封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵浮庐,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我柬焕,道長(zhǎng)审残,這世上最難降的妖魔是什么梭域? 我笑而不...
    開(kāi)封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮维苔,結(jié)果婚禮上碰辅,老公的妹妹穿的比我還像新娘。我一直安慰自己介时,他們只是感情好没宾,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著沸柔,像睡著了一般循衰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上褐澎,一...
    開(kāi)封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天会钝,我揣著相機(jī)與錄音,去河邊找鬼工三。 笑死迁酸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的俭正。 我是一名探鬼主播奸鬓,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼掸读!你這毒婦竟也來(lái)了串远?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤儿惫,失蹤者是張志新(化名)和其女友劉穎澡罚,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體肾请,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡留搔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了铛铁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隔显。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖避归,靈堂內(nèi)的尸體忽然破棺而出荣月,到底是詐尸還是另有隱情管呵,我是刑警寧澤梳毙,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站捐下,受9級(jí)特大地震影響账锹,放射性物質(zhì)發(fā)生泄漏萌业。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一奸柬、第九天 我趴在偏房一處隱蔽的房頂上張望生年。 院中可真熱鬧,春花似錦廓奕、人聲如沸抱婉。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蒸绩。三九已至,卻和暖如春铃肯,著一層夾襖步出監(jiān)牢的瞬間患亿,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工押逼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留步藕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓挑格,卻偏偏與公主長(zhǎng)得像咙冗,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子恕齐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345