我們前面完成了Dart語言基礎特性的學習,包括基礎語法概覽、迭代集合、非同步編程、Mixin高級特性和變數等。今天我們來學習Dart的庫相關知識,包括如何導入庫、指定庫首碼、導入部分或者排除部分庫、延遲導入庫等,最後看下Dart中67個關鍵字作為標識符的一些約束…… ...
Dart官網文檔:https://dart.dev/language/libraries
重要說明:本博客基於Dart官網文檔,但並不是簡單的對官網進行翻譯,在覆蓋核心功能情況下,我會根據個人研發經驗,加入自己的一些擴展問題和場景驗證。
Dart中的庫(Library)
Dart語言對代碼的復用下了不少功夫,如前面講到的Mixin
高級特性實現類級別代碼復用。本文介紹另一種更寬廣的代碼復用:庫。
Dart庫可以認為是一組復用類、功能等的集合,它則代表了一個共用的代碼模塊,任何一個.dart
文件都是一個庫。
Dart庫有一個隱含的規則:凡是以下劃線_
開頭的標識符僅在本庫內部可見,其他在庫內外部均可見。(Dart沒有private/protected/public可見域標識符,那麼對應Java語言,下劃線_
開頭為private
,其他的為public
,Dart沒有protected)。
Dart庫可以基本可分為3種,建議在使用時嚴格按照這3類導入庫:
- Dart中的內置庫,即SDK中的庫(對於Java語言如java.util.Map),以
dart:
作為命名空間。 - Dart包中心倉庫的庫(對於Java語言為Maven中心倉庫),以
package:
作為命名空間。 - 本地文件代碼庫,以相對
路徑
或者絕對路徑作為命名空間。當然,本地代碼塊也可以使用package
作為命名空間,容易和第2中混淆,因此不推薦。
如何使用庫(import關鍵字)
通過import
關鍵字指定在一個庫中使用另外一個命名空間的庫。
代碼樣例:如下代碼,我們導入了Dart內置的html
庫、中心倉庫get
庫,和本地
庫。
// 內置庫
import 'dart:html';
// 中心倉庫
import 'package:get/get.dart';
// 本地代碼庫
import '../01-ntopic-hellodart.dart';
指定庫首碼(as關鍵字)
研發過程中,我們有時會導入有相同標識符,那麼在使用過程中就會產生衝突,這時可以通過as
關鍵字進行重命名庫,同時在使用的時候,增加首碼進行區分。
代碼樣例:如下代碼,我們導入了lib1和lib2兩個庫,它們都有Element這個類。
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// `lib1`庫中Element類
Element element1 = Element();
// `lib2`庫中Element類,通過`lib2`首碼解決衝突
lib2.Element element2 = lib2.Element();
導入部分庫(show/hide關鍵字)
我們有時候只需要用到某個庫的一部分代碼或者類,或者需要排除某個庫中指定的代碼,通過增加show
和hide
關鍵字可實現。
代碼樣例:如下代碼,我們用到了lib1和lib2兩個庫,lib1通過show
僅導入了foo這個標識符(類名、常量名等),而lib2通過hide
導入除foo之外的其他所有標識符。
// 僅導入`foo`
import 'package:lib1/lib1.dart' show foo;
// 導入除`foo`之外所有
import 'package:lib2/lib2.dart' hide foo;
延遲導入庫(deferred as關鍵字)
Web應用中通過延遲導入庫,可以實現按需載入,如下幾種常見的應用場景:
- 減少Web應用的啟動時間。
- A/B測試,比如切流不同的演算法庫。
- 不常用的功能,比如可選頁面、彈窗等。
代碼樣例:如下代碼,通過deferred as
關鍵字,實現延遲導入庫,在實際使用庫功能時需要導入庫(如:await hello.loadLibrary();
),在庫載入完成之前,會阻塞代碼執行。執行loadLibrary()
方法僅實際載入庫一次,後續調用該方法不會重覆載入。
// 1. 延遲導入庫
import 'package:greetings/hello.dart' deferred as hello;
// 2. 實際使用時,使用庫首碼
Future<void> greet() async {
// 載入庫,載入成功之前阻塞後續代碼執行,多次調用僅載入一次
await hello.loadLibrary();
hello.printGreeting();
}
特別註意:
- 延遲導入庫中的常量,在該庫導入之前並不存在,因此它們並不是導入庫(即使用它們的文件)中的常量。
- 延遲導入庫在導入之前並不存在,因此導入庫不能使用它們的類型(包括類、枚舉等),可以考慮把公共代碼(如基礎類、介面等)抽取出來作為單獨的庫,讓延遲導入庫和導入庫共同導入使用。
- 當使用
deferred as XXX
延遲導入庫時,Dart隱含的給loadLibrary()
增加了XXX
命名空間。如上代碼,loadLibrary()
方法是非同步的,返回一個Future
。
Dart中的關鍵字(共67個)
Dart官方文檔:https://dart.dev/language/keywords
Dart關鍵字一共包含67個,本博客不重覆列出這67個關鍵字,僅對關鍵字進行說明:
- 儘量避免使用這些關鍵字作為標識符,如有必要,表格中有
1
,2
,3
上標的關鍵字在部分常見可以使用作為標識符。 - 上標為
1
的關鍵字與上下文有關,離開了上下文,這些關鍵字可以作為標識符。如show
和hide
關鍵在只在導入庫上下文文中用到,其他地方可以正常作為標識符。 - 上標為
2
的關鍵字是Dart內置的標識符,它們在大部分場景可以使用,但是禁止在類名、類型名和指定庫的首碼(其實也是類型的一種)。 - 上標為
3
的關鍵字(共2個:await
/yield
)限制在非同步編程場景使用,在標記為async
/async*
/sync*
同步和非同步函數內部,禁止使用。
我的本博客原地址:https://ntopic.cn/p/2023100201
本文作者:奔跑的蝸牛,轉載請註明原文鏈接:https://ntopic.cn