基本概念
什么是 Dart 库(library)
库是 Dart 代码的组织单位,用于代码模块化和复用。
每个 Dart 文件默认就是一个库,库可以包含类、函数、变量等。
你可以用 library 关键字显式声明库名,但不强制。
通过 import 导入库,实现代码分割和复用。
Dart 项目中的 lib 目录
在 Dart(特别是 Flutter)项目里,lib 是默认的主代码目录,存放你项目的 Dart 代码。
项目中的 lib 目录就是你定义的“公共库”的集合。
在项目中,可以把不同功能拆分成不同 Dart 文件,形成多个库。
可以用子文件夹管理代码,这样清晰分层,方便维护。
lib/
├── utils/
│ ├── string_utils.dart
│ └── date_utils.dart
├── models/
│ └── user.dart
├── services/
│ └── api_service.dart
└── main.dart
导入库(import)
导入核心库(Dart SDK 自带库)
Dart 自带了很多核心库(如 dart:core, dart:io, dart:async 等),可以直接导入使用。
dart: 开头表示 Dart SDK 自带库。
这些库提供基础功能,比如文件操作、数学函数、异步编程等。
import 'dart:io';
void main() {
var f = new File('README.md');
var content = f.readAsStringSync();
print(content);
}
导入第三方库(pub 包)
使用 Dart/Flutter 的包管理工具 pub 安装的第三方库,通过包名导入。
import 'package:dio/dio.dart';
void main() async {
Dio dio = Dio();
Response<String> response = await dio.get("https://www.baidu.com");
print(response.data);
print("----------------------------");
}
package:开头表示从项目依赖的包中导入。import 'package:包名/文件.dart';需要先在
pubspec.yaml中添加依赖# Add regular dependencies here. dependencies: # path: ^1.8.0 dio: ^4.0.6再运行
flutter pub get或dart pub get(base) xieshaolin@xieshaolindeMacBook-Pro dart_learn % dart pub get Resolving dependencies... Downloading packages... dio 4.0.6 (affected by advisories: [^0], [^1], 5.9.0 available) lints 5.1.1 (6.0.0 available) Got dependencies! Dependencies are affected by security advisories: [^0]: https://github.com/advisories/GHSA-9324-jv53-9cc8 [^1]: https://github.com/advisories/GHSA-jwpw-q68h-r678 2 packages have newer versions incompatible with dependency constraints. Try `dart pub outdated` for more information.
导入 Git 仓库库的包
在
pubspec.yaml中可以指定依赖来自 Git 仓库:# Add regular dependencies here. dependencies: # path: ^1.8.0 dio: ^4.0.6 intl: # 这里填Git项目的名字 git: url: https://github.com/dart-lang/intl.git # 这里填Git项目的地址 ref: master # 也可以指定具体分支、标签或 commit再运行
flutter pub get或dart pub get拉去仓库(base) xieshaolin@xieshaolindeMacBook-Pro dart_learn % dart pub get Resolving dependencies... Downloading packages... dio 4.0.6 (affected by advisories: [^0], [^1], 5.9.0 available) lints 5.1.1 (6.0.0 available) Got dependencies! Dependencies are affected by security advisories: [^0]: https://github.com/advisories/GHSA-9324-jv53-9cc8 [^1]: https://github.com/advisories/GHSA-jwpw-q68h-r678 2 packages have newer versions incompatible with dependency constraints. Try `dart pub outdated` for more information.导入包并使用
import 'package:intl/intl.dart'; void main() { var now = DateTime.now(); var formatter = DateFormat('yyyy-MM-dd'); print(formatter.format(now)); // 输出类似 2025-08-11 }安装依赖后,导入方式与普通包相同,
import 'package:包名/文件.dart';。
导入项目内的类文件(本地文件)
想在 bin/dart_learn.dart 中导入 lib/testImport/test.dart
dart_learn/
├─ lib/
│ └─ testImport/
│ └─ test.dart
└─ bin/
└─ dart_learn.dart
相对路径导入
import '../lib/testImport/test.dart';
void main() {
var p = Phone();
p.call();
var a = Android();
a.call();
a.playStore();
var i = Ios();
i.call();
i.appleStore();
}
使用相对路径,从当前文件位置开始计算路径。
适合小项目或局部文件导入。
包路径导入(推荐)
import 'package:your_project_name/models/user.dart';
import 'package:your_project_name/utils/helper.dart';
以包名开头,路径从 lib/ 目录开始写。
方便跨文件夹引用,推荐用于大型项目。
// 注意要放在lib下面
import 'package:dart_learn/testImport/test.dart';
void main() {
var p = Phone();
p.call();
var a = Android();
a.call();
a.playStore();
var i = Ios();
i.call();
i.appleStore();
}
导入时的别名
import 'package:foo/foo.dart' as fooLib;
void main() {
fooLib.someFunction();
}
导入时的隐藏
hide — 隐藏某些符号
- 用来导入一个库时排除掉指定的类、函数、变量等,让它们在当前文件不可见。
- 也就是想排除某些类类、函数、变量等
- 适合避免名字冲突或者不需要使用库里的某些成员。
假设有库 foo.dart:
class SomeClass {
void method() => print('SomeClass method');
}
class OtherClass {
void method() => print('OtherClass method');
}
现在你想导入 foo.dart,但不想让 SomeClass 出现在当前文件:
import 'package:foo/foo.dart' hide SomeClass;
void main() {
// SomeClass 会报错,因为被隐藏了
// var a = SomeClass(); // Error: Undefined class 'SomeClass'
var b = OtherClass();
b.method(); // 正常调用
}
导入时的筛选
show — 只导入部分符号
- 用来只导入指定的类、函数、变量,其他都不导入。
- 适合只想使用库里部分功能,减少命名空间污染。
继续上面 foo.dart,你只想使用 SomeClass:
import 'package:foo/foo.dart' show SomeClass;
void main() {
var a = SomeClass();
a.method();
// OtherClass 未导入,下面会报错
// var b = OtherClass(); // Error: Undefined class 'OtherClass'
}
延迟载入
什么是延迟载入?
- 延迟载入指的是在程序启动时不马上加载某个库,而是在首次使用时才加载它。
- 这样可以减少启动时的开销,加快应用启动速度。
- 特别适合大型库、功能模块或不常用的代码。
Dart 中如何实现延迟载入?
使用 deferred 关键字配合 import 实现。
import 'package:some_package/heavy_lib.dart' deferred as heavy; //必须要有别名
- 这里
heavy是该库的别名,使用时需要通过它调用。 - 库在程序开始时不会加载,直到你显式加载。
如何加载延迟库?
调用 loadLibrary() 方法加载库,返回一个 Future。
await heavy.loadLibrary();
heavy.someFunction();
只有调用了 loadLibrary(),库代码才会被真正加载。
具体示例
假设有一个很大的库 big_module.dart:
// big_module.dart
void heavyTask() {
print('执行耗时任务...');
}
主程序:
import 'big_module.dart' deferred as big; // 只能通过别名
void main() async {
print('程序启动');
// 延迟加载 big_module.dart
await big.loadLibrary();
// 调用延迟库中的函数
big.heavyTask();
}
运行效果:
程序启动
执行耗时任务...
- 注意:调用
loadLibrary()是异步的,需要await。
延迟载入的优点
提高启动速度:不需要一次性加载所有代码。
节省内存:不使用时不占用内存。
按需加载:用户点击某功能时才加载对应模块
注意事项
- 延迟库只能访问通过别名引用的成员,不能直接用导入路径访问。
- 延迟加载库的初始化工作(比如静态变量)会在
loadLibrary()时执行。 - 延迟加载不能用于导入相互依赖的库(循环依赖)。
导出库(export)
基本介绍
在 Dart 中,export 主要用于 库(library)之间的共享。它的作用是:把一个库的 API 再次暴露出去,让使用方能间接访问。
export 的应用场景
- 库的对外接口:比如
flutter/material.dart其实内部就是一个大合集库,export了很多 Material 相关的组件。 - 统一管理工具函数:像上面例子,把工具函数统一到
utils.dart,便于调用。 - 封装 SDK:如果你写了一个 Dart 包,可以用
export来对外暴露有限 API,而把内部实现隐藏。
基本用法
假设有三个文件:
math_utils.dart
library math_utils;
int add(int a, int b) => a + b;
int subtract(int a, int b) => a - b;
string_utils.dart
library string_utils;
String capitalize(String s) => s[0].toUpperCase() + s.substring(1);
utils.dart
// utils.dart 并不自己实现功能,而是通过 export 暴露其它库
export 'math_utils.dart';
export 'string_utils.dart';
main.dart
import 'utils.dart';
void main() {
print(add(3, 5)); // 8
print(capitalize("dart")); // Dart
}
可以看到 main.dart 并没有直接导入 math_utils.dart 和 string_utils.dart,而是通过 utils.dart 统一出口 来使用。
这在项目中很常见,可以把多个库集中导出,方便管理。
show 与 hide
export 和 import 一样,可以 精确控制暴露的内容。
只导出指定内容 (show)
export 'math_utils.dart' show add;
这样 utils.dart 只会导出 add 方法,而不会导出 subtract。
隐藏某些内容 (hide)
export 'math_utils.dart' hide subtract;
这样导出 math_utils.dart 里的所有内容,但不包括 subtract。
给导出的库加前缀
如果多个库中有同名方法,可以给导出的库设置别名:
export 'math_utils.dart' as math;
export 'string_utils.dart' as str;
使用时:
import 'utils.dart';
void main() {
print(math.add(1, 2));
print(str.capitalize("hello"));
}