写在前面
Dart 里关于库的一些概念和用法。
内容
在 Dart 里面库可以分为三种:
- 自定义库
- 系统库
- 第三方库
自定义库
自定义库就是我们自己来写的库,在 Dart 里,每个 Dart 文件默认都是一个库,只是没有使用library
关键字来声明。
例如下面两个是等同的:
library hello;
class Hello{}
---
class Hello{}
那么现在我们就知道每个 Dart 文件里其实都隐含着一个库的概念。
我们知道在 Dart 里使用_
(下划线)来表示私有,那么在一个 Dart 文件里我们对一个类使用_
,表示的就是这个类只能在库内被访问的意思:
下面的例子里_Hi
类就不能被别的文件访问到了。
library hello;
class Hello{}
class _Hi {}
---
class Hello{}
class _Hi {}
一般情况是建议忽略使用library
关键字,除非说你想为你的库生成 API 文档(Dart 里面有一个叫 dartdoc 的工具,用于生成 API 文档)。
在导入库的时候使用的是import 'package:xxx.dart';
系统库
在导入库的时候使用的是import 'dart:xxx';
其中有一个叫 core 的库,import 'dart:core';
这句话是不用写的,它默认引入。这也是我们在使用一些系统类的时候,如DateTime
不需要引入库的原因。
在Core libraries里列出了 Dart 提供的相关核心库。
第三方库
在pubspec.yaml
里引入第三方库。pubspec.yaml
里的相关内容可以查看 The pubspec file
在导入库的时候使用的是import 'package:xxx.dart';
库的部分引入
我们可以针对库的内容做部分引入:
- 包含引入(show)
- 排除引入(hide)
show
在 hello.dart 里声明两个类。
// hello.dart
class Hello {}
class Hi {}
在引入的时候我们做如下操作:
// main.dart
import 'hello.dart' show Hello;
void main() {
Hello();
// 报错 The function 'Hi' isn't defined.
Hi();
}
hide
以上面的例子,如果改成下面的例子,效果也是一样的:
// main.dart
import 'hello.dart' hide Hi;
void main() {
Hello();
// 报错 The function 'Hi' isn't defined.
Hi();
}
指定库的命名前缀
在引用库的时候,有时会出现一些重名冲突的情况(例如不同的文件里却有相同的命名函数或类),或者有时我们出于某些原因想自己在某个文件里修改这个库的名字。
此时就可以使用 as 来给库一个别名,在使用的时候就要带上这个别名。
import 'hello.dart' as h;
void main() {
h.Hello();
h.Hi();
}
延迟引入(懒加载)
Dart 里允许我们延迟引入库,使用的是deferred as
。
import 'hello.dart' deferred as h;
void main() {
// 直接调用会报错
h.Hello();
h.Hi();
}
由于使用了deferred as
,当我们想要它起作用的时候,就应该先调用它的loadLibrary()
方法,这是个异步方法,因此:
import 'hello.dart' deferred as h;
void main() {
greet();
}
Future greet() async {
await h.loadLibrary();
h.Hello();
h.Hi();
}
官方给我们建议一些使用懒加载库的场景:
- 想减少 Web app 的初始化启动时间
- 想在 A/B 测试里尝试替换算法的实现
- 想加载一些很少使用到的方法,比方说弹窗
loadLibrary()
方法我们可以调用多次,但实际上它只会加载一次。由于它是懒加载,因此库里面定义了常量的话,也需要加载后才能被使用。
库的部分引入
在 Dart 里我们通过使用part
和part of
来对库进行一个拆分的处理。
例如有一个主库,和多个分库,这样我们就可以让不同的人负责一个库,最后把它们合到一个主库里:
// sub2_lib.dart
// 与主库建立联系
part of main_lib;
class Sub2Lib {
Sub2Lib() {
print("Sub2Lib");
}
}
// sub1_lib.dart
part of main_lib;
class Sub1Lib {
Sub1Lib() {
print("Sub1Lib");
}
}
// main_lib.dart
// 主库名应该与子库里建立联系的库名一致
library main_lib;
// 引入子库
part 'sub1_lib.dart';
part 'sub2_lib.dart';
// main.dart
import 'main_lib.dart';
void main() {
Sub1Lib();
Sub2Lib();
}