import 和library關(guān)鍵字可以幫助你創(chuàng)建一個(gè)模塊化和可共享的代碼庫(kù)。代碼庫(kù)不僅只是提供 API 而且還起到了封裝的作用:以下劃線(_)開(kāi)頭的成員僅在代碼庫(kù)中可見(jiàn)。每個(gè) Dart 程序都是一個(gè)庫(kù),即便沒(méi)有使用關(guān)鍵字 library 指定。
使用庫(kù)
使用 import 來(lái)指定命名空間以便其它庫(kù)可以訪問(wèn)。
比如你可以導(dǎo)入代碼庫(kù) dart:html 來(lái)使用 Dart Web 中相關(guān) API:
import 'dart:html';
import 的唯一參數(shù)是用于指定代碼庫(kù)的 URI,對(duì)于 Dart 內(nèi)置的庫(kù),使用 dart:xxxxxx的形式。而對(duì)于其它的庫(kù),你可以使用一個(gè)文件系統(tǒng)路徑或者以 package:xxxxxx 的形式。package:xxxxxx 指定的庫(kù)通過(guò)包管理器(比如 pub 工具)來(lái)提供:
import 'package:test/test.dart';
指定庫(kù)前綴
如果你導(dǎo)入的兩個(gè)代碼庫(kù)有沖突的標(biāo)識(shí)符,你可以為其中一個(gè)指定前綴。比如如果 library1 和 library2 都有 Element 類(lèi),那么可以這么處理:
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// 使用 lib1 的 Element 類(lèi)。
Element element1 = Element();
// 使用 lib2 的 Element 類(lèi)。
lib2.Element element2 = lib2.Element();
導(dǎo)入庫(kù)的一部分
如果你只想使用代碼庫(kù)中的一部分,你可以有選擇地導(dǎo)入代碼庫(kù)。例如:
// 只導(dǎo)入 lib1 中的 foo。(Import only foo).
import 'package:lib1/lib1.dart' show foo;
// 導(dǎo)入 lib2 中除了 foo 外的所有。
import 'package:lib2/lib2.dart' hide foo;
延遲加載庫(kù)
延遲加載(也常稱(chēng)為 懶加載)允許應(yīng)用在需要時(shí)再去加載代碼庫(kù),下面是可能使用到延遲加載的場(chǎng)景:
- 為了減少應(yīng)用的初始化時(shí)間。
- 處理 A/B 測(cè)試,比如測(cè)試各種算法的不同實(shí)現(xiàn)。
- 加載很少會(huì)使用到的功能,比如可選的屏幕和對(duì)話(huà)框。
注意:目前只有 dart2js 支持延遲加載 。Flutter、Dart VM以及 DartDevc 目前都不支持延遲加載。你可以查閱 issue #33118 和 issue #27776 獲取更多的相關(guān)信息。
使用 deferred as關(guān)鍵字來(lái)標(biāo)識(shí)需要延時(shí)加載的代碼庫(kù):
import 'package:greetings/hello.dart' deferred as hello;
當(dāng)實(shí)際需要使用到庫(kù)中 API 時(shí)先調(diào)用 loadLibrary 函數(shù)加載庫(kù):
Future greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
在前面的代碼,使用 await 關(guān)鍵字暫停代碼執(zhí)行直到庫(kù)加載完成。更多關(guān)于 async 和 await 的信息請(qǐng)參考異步支持。
loadLibrary函數(shù)可以調(diào)用多次也沒(méi)關(guān)系,代碼庫(kù)只會(huì)被加載一次。
當(dāng)你使用延遲加載的時(shí)候需要牢記以下幾點(diǎn):
- 延遲加載的代碼庫(kù)中的常量需要在代碼庫(kù)被加載的時(shí)候才會(huì)導(dǎo)入,未加載時(shí)是不會(huì)導(dǎo)入的。
- 導(dǎo)入文件的時(shí)候無(wú)法使用延遲加載庫(kù)中的類(lèi)型。如果你需要使用類(lèi)型,則考慮吧接口類(lèi)型轉(zhuǎn)移到另一個(gè)庫(kù)中然后讓兩個(gè)庫(kù)都分別導(dǎo)入這個(gè)接口庫(kù)。
- Dart會(huì)隱式地將
loadLibrary方法導(dǎo)入到使用了deferred as *命名空間*的類(lèi)中。loadLibrary函數(shù)返回的是一個(gè) Future。
實(shí)現(xiàn)庫(kù)
查閱創(chuàng)建依賴(lài)庫(kù)包可以獲取有關(guān)如何實(shí)現(xiàn)庫(kù)包的建議,包括:
如何組織庫(kù)的源文件。
如何使用 export 命令。
何時(shí)使用 part 命令。
何時(shí)使用 library 命令。
如何使用倒入和導(dǎo)出命令實(shí)現(xiàn)多平臺(tái)的庫(kù)支持。
變量聲明的可見(jiàn)性
Dart 中并沒(méi)有 public、protected、private這些關(guān)鍵字,我們只要在聲明變量與方法時(shí),在前面加上_即可作為 private方法使用。如果不加_,則默認(rèn)為public。不過(guò),_的限制范圍并不是類(lèi)訪問(wèn)級(jí)別的,而是庫(kù)訪問(wèn)級(jí)別。