Dart Libraries & Imports 完全指南
📚 目录
基础概念
什么是库(Library)?
在Dart中,每个程序都是一个库,即使没有显式使用library关键字。库是Dart代码的基本组织单位,具有以下特点:
- 封装单元:提供代码的逻辑分组和封装
- 命名空间:避免全局命名冲突
- 可见性控制:通过下划线前缀实现私有成员
- 重用性:可以被其他库导入和使用
// 显式声明库名(可选)
library my_awesome_library;
// 库的内容
class MyClass {
// 公共成员
String publicField = 'visible everywhere';
// 私有成员(只在当前库内可见)
String _privateField = 'only visible in this library';
}
库的类型
-
内置库:Dart SDK提供的核心库
dart:core- 核心功能(自动导入)dart:async- 异步编程dart:io- 输入输出操作dart:math- 数学计算dart:convert- 数据转换
-
第三方包:通过pub.dev分发的库
- 使用
package:前缀导入 - 在
pubspec.yaml中声明依赖
- 使用
-
本地库:项目内的自定义库
- 使用相对路径导入
- 通常放在
lib/目录下
库的定义与结构
标准库结构
lib/
├── my_package.dart # 主导出文件
├── src/ # 私有实现(不直接导入)
│ ├── models/
│ │ ├── user.dart
│ │ └── product.dart
│ ├── services/
│ │ ├── api_service.dart
│ │ └── cache_service.dart
│ └── utils/
│ ├── validators.dart
│ └── formatters.dart
└── widgets/ # 公共组件
├── buttons.dart
└── cards.dart
声明库
// 方式1:隐式库(推荐)
// 每个.dart文件自动是一个库
// 方式2:显式声明库名
library my_utils;
import 'dart:math';
// ... 库的内容
使用part和part of
当一个库过大时,可以拆分为多个文件:
// main_library.dart
library main_library;
part 'src/part1.dart';
part 'src/part2.dart';
class MainClass {
// 主要功能
}
// src/part1.dart
part of '../main_library.dart';
// 这个文件的内容属于 main_library
class PartClass1 {
// 可以访问主库的私有成员
}
重要提示:
- 推荐使用URI而不是库名
- part文件不能有独立的import语句
- 所有part共享同一个命名空间
导入机制详解
基本导入语法
// 1. 导入内置库
import 'dart:async';
import 'dart:convert';
import 'dart:io';
// 2. 导入第三方包
import 'package:http/http.dart';
import 'package:json_annotation/json_annotation.dart';
// 3. 导入本地文件
import 'utils.dart';
import 'models/user.dart';
import '../shared/constants.dart';
导入顺序规范
遵循以下顺序,各组之间用空行分隔:
// 1. Dart内置库
import 'dart:async';
import 'dart:convert';
import 'dart:io';
// 2. 第三方包
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:provider/provider.dart';
// 3. 本地库文件
import '../models/user.dart';
import '../services/api_service.dart';
import 'widgets/custom_button.dart';
库前缀(as 关键字)
解决命名冲突:
import 'dart:math' as math;
import 'package:vector_math/vector_math.dart' as vector;
void main() {
// 使用前缀区分同名类
final random = math.Random();
final matrix = vector.Matrix4.identity();
// 访问常量
print('π = ${math.pi}');
}
选择性导入
show关键字:只导入指定内容
// 只导入特定的类或函数
import 'dart:math' show Random, pi, sin, cos;
import 'package:http/http.dart' show get, post;
void main() {
final random = Random(); // ✅ 可用
print(pi); // ✅ 可用
// print(e); // ❌ 不可用,未导入
}
hide关键字:排除特定内容
// 导入除了指定内容外的所有内容
import 'dart:convert' hide Utf8Decoder;
import 'package:my_package/my_package.dart' hide InternalClass;
void main() {
jsonEncode({'key': 'value'}); // ✅ 可用
// Utf8Decoder(); // ❌ 不可用,被隐藏
}
延迟加载(deferred as)
用于按需加载大型库,减少应用启动时间:
import 'package:heavy_library/heavy_library.dart' deferred as heavy;
Future<void> useHeavyLibrary() async {
// 在使用前必须先加载
await heavy.loadLibrary();
// 现在可以使用库中的功能
heavy.someHeavyFunction();
}
// 检查库是否已加载(Dart 2.19+)
bool isLoaded = heavy.isLoaded;
延迟加载的限制:
- 不能使用延迟库的类型作为编译时常量
- 不能在延迟库的类型上使用is表达式
- 必须先调用
loadLibrary()
条件导入
根据平台或环境导入不同的实现:
// 根据平台导入不同实现
import 'stub_implementation.dart'
if (dart.library.io) 'io_implementation.dart'
if (dart.library.html) 'web_implementation.dart';
// 检查特定库是否可用
import 'default_implementation.dart'
if (dart.library.js) 'js_implementation.dart';
常用的条件:
dart.library.io- 服务器/移动端/桌面dart.library.html- Web浏览器dart.library.js- JavaScript环境dart.library.ffi- FFI支持
导出机制
基本导出
使用export关键字重新导出其他库的内容:
// my_package.dart - 主导出文件
library my_package;
// 导出所有子模块
export 'src/models.dart';
export 'src/services.dart';
export 'src/utils.dart';
// 用户只需导入一个文件
// import 'package:my_package/my_package.dart';
选择性导出
// 只导出特定内容
export 'src/internal_module.dart' show PublicClass, publicFunction;
// 导出除了特定内容外的所有内容
export 'src/another_module.dart' hide InternalClass, _privateFunction;
// 可以同时使用show和hide(但通常不推荐)
export 'src/complex_module.dart'
show Class1, Class2
hide InternalDetail;
转发导出
// utils.dart
export 'dart:math' show Random, pi;
export 'package:meta/meta.dart' show required, immutable;
// 用户代码
import 'utils.dart';
void main() {
final random = Random(); // 来自dart:math
print(pi); // 来自dart:math
// 可以使用@required等注解 // 来自package:meta
}
库的可见性与封装
私有成员规则
以下划线(_)开头的标识符只在库内可见:
// my_library.dart
class PublicClass {
String publicField = 'Everyone can see this';
String _privateField = 'Only this library can see this';
void publicMethod() {
// 可以调用私有方法
_privateMethod();
}
void _privateMethod() {
print('Private method');
}
}
// 私有顶级函数
void _privateTopLevelFunction() {
print('Private at library level');
}
// 私有常量
const String _privateConstant = 'Secret value';
库级别的封装
// calculator.dart
library calculator;
// 公共API
double add(double a, double b) => a + b;
double multiply(double a, double b) => a + b;
// 私有实现细节
double _validateInput(double value) {
if (value.isNaN || value.isInfinite) {
throw ArgumentError('Invalid input: $value');
}
return value;
}
访问控制最佳实践
// good_encapsulation.dart
class DataProcessor {
// 公共接口
List<String> processData(List<String> input) {
final validated = _validateInput(input);
final processed = _transformData(validated);
return _formatOutput(processed);
}
// 私有实现 - 用户不需要知道这些细节
List<String> _validateInput(List<String> input) { /* ... */ }
List<String> _transformData(List<String> data) { /* ... */ }
List<String> _formatOutput(List<String> data) { /* ... */ }
}
高级特性
库的元数据
library my_package;
/// 库的详细文档
///
/// 这个库提供了以下功能:
/// - 数据处理工具
/// - 验证函数
/// - 格式化工具
///
/// 使用示例:
/// ```dart
/// import 'package:my_package/my_package.dart';
///
/// final result = processData(['item1', 'item2']);
/// ```
@Deprecated('Use new_package instead')
@Since('1.0.0')
library my_package;
// 版本信息
const String version = '2.1.0';
动态导入(实验性)
// 动态加载库(在某些平台上可用)
Future<void> loadFeature(String featureName) async {
switch (featureName) {
case 'advanced':
final advancedLib = await import('package:my_app/advanced.dart');
advancedLib.initialize();
break;
case 'experimental':
final expLib = await import('package:my_app/experimental.dart');
expLib.setup();
break;
}
}
库的配置
// config.dart
library config;
class LibraryConfig {
static bool _debugMode = false;
static String _apiEndpoint = 'https://api.example.com';
static void configure({
bool? debugMode,
String? apiEndpoint,
}) {
if (debugMode != null) _debugMode = debugMode;
if (apiEndpoint != null) _apiEndpoint = apiEndpoint;
}
static bool get debugMode => _debugMode;
static String get apiEndpoint => _apiEndpoint;
}
最佳实践
1. 导入组织
// ✅ 良好的导入组织
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import '../models/user.dart';
import '../services/auth_service.dart';
import 'widgets/loading_indicator.dart';
2. 库的命名
// ✅ 好的库名
library user_management;
library data_validation_utils;
library network_client;
// ❌ 避免的库名
library Library;
library Utils;
library MyLib;
3. API设计
// ✅ 清晰的公共API
library math_utils;
export 'src/calculators.dart' show BasicCalculator, AdvancedCalculator;
export 'src/constants.dart' show MathConstants;
export 'src/validators.dart' show NumberValidator;
// 隐藏内部实现
// src/internal/ 目录下的文件不被导出
4. 文档编写
/// 用户认证库
///
/// 提供用户登录、注册、会话管理等功能。
///
/// 主要功能:
/// - [AuthService] - 认证服务
/// - [TokenManager] - 令牌管理
/// - [UserSession] - 用户会话
///
/// 使用示例:
/// ```dart
/// final authService = AuthService();
/// final user = await authService.login('email', 'password');
/// ```
library auth;
/// 登录用户
///
/// [email] 用户邮箱
/// [password] 用户密码
///
/// 返回 [User] 对象,如果认证失败则抛出 [AuthException]
///
/// 示例:
/// ```dart
/// try {
/// final user = await login('user@example.com', 'password123');
/// print('Welcome ${user.name}!');
/// } on AuthException catch (e) {
/// print('Login failed: ${e.message}');
/// }
/// ```
Future<User> login(String email, String password) async {
// 实现...
}
5. 错误处理
// custom_exceptions.dart
library custom_exceptions;
/// 基础异常类
abstract class AppException implements Exception {
const AppException(this.message);
final String message;
@override
String toString() => 'AppException: $message';
}
/// 网络相关异常
class NetworkException extends AppException {
const NetworkException(super.message);
}
/// 验证异常
class ValidationException extends AppException {
const ValidationException(super.message, this.field);
final String field;
}
6. 版本管理
// version.dart
library version;
/// 包版本信息
class PackageVersion {
static const String current = '2.1.0';
static const int major = 2;
static const int minor = 1;
static const int patch = 0;
/// 检查是否兼容指定版本
static bool isCompatibleWith(String version) {
// 实现版本兼容性检查
return true;
}
}
常见问题与解决方案
1. 循环依赖
问题:A库导入B库,B库也导入A库
// ❌ 循环依赖示例
// user.dart
import 'order.dart';
class User {
List<Order> orders = [];
}
// order.dart
import 'user.dart';
class Order {
User user;
}
解决方案:
// ✅ 使用接口解耦
// interfaces.dart
abstract class IUser {
String get id;
String get name;
}
// user.dart
import 'interfaces.dart';
import 'order.dart';
class User implements IUser {
String id;
String name;
List<Order> orders = [];
}
// order.dart
import 'interfaces.dart';
class Order {
IUser user; // 依赖接口而非具体类
}
2. 命名冲突
问题:多个库有同名的类或函数
// ❌ 命名冲突
import 'dart:math'; // 有Random类
import 'package:my_package/random.dart'; // 也有Random类
// 编译错误:不知道使用哪个Random
final random = Random();
解决方案:
// ✅ 使用前缀
import 'dart:math' as math;
import 'package:my_package/random.dart' as custom;
final mathRandom = math.Random();
final customRandom = custom.Random();
// ✅ 或使用选择性导入
import 'dart:math' show Random;
import 'package:my_package/random.dart' hide Random;
3. 私有成员访问
问题:尝试从外部库访问私有成员
// ❌ 无法访问私有成员
// my_library.dart
class MyClass {
String _privateField = 'secret';
}
// other_file.dart
import 'my_library.dart';
void main() {
final obj = MyClass();
print(obj._privateField); // 编译错误
}
解决方案:
// ✅ 提供公共访问器
// my_library.dart
class MyClass {
String _privateField = 'secret';
String get privateField => _privateField; // 只读访问
void updatePrivateField(String value) { // 受控修改
_privateField = value;
}
}
4. 延迟加载问题
问题:使用延迟库前未调用loadLibrary()
// ❌ 错误使用延迟库
import 'package:heavy_lib/heavy_lib.dart' deferred as heavy;
void main() {
heavy.someFunction(); // 运行时错误
}
解决方案:
// ✅ 正确使用延迟库
import 'package:heavy_lib/heavy_lib.dart' deferred as heavy;
Future<void> main() async {
await heavy.loadLibrary();
heavy.someFunction(); // 正常工作
}
// ✅ 带错误处理的版本
Future<void> safeLoadHeavyLib() async {
try {
await heavy.loadLibrary();
heavy.someFunction();
} catch (e) {
print('Failed to load heavy library: $e');
}
}
性能优化
1. 减少导入数量
// ❌ 导入整个库但只用一小部分
import 'dart:convert';
void main() {
jsonEncode({'key': 'value'}); // 只用了一个函数
}
// ✅ 选择性导入
import 'dart:convert' show jsonEncode;
void main() {
jsonEncode({'key': 'value'});
}
2. 延迟加载大型库
// ✅ 对大型或很少使用的库使用延迟加载
import 'package:charts_flutter/flutter.dart' deferred as charts;
import 'package:image/image.dart' deferred as image_lib;
Future<void> showChart() async {
await charts.loadLibrary();
// 使用图表库
}
Future<void> processImage() async {
await image_lib.loadLibrary();
// 使用图像处理库
}
3. 避免不必要的re-export
// ❌ 过度导出
export 'dart:core'; // 不必要,core已自动可用
export 'package:huge_library/huge_library.dart'; // 可能导入很多不需要的内容
// ✅ 精确导出
export 'package:huge_library/huge_library.dart'
show SpecificClass, specificFunction;
4. Tree-shaking优化
// ✅ 写出tree-shaking友好的代码
// utils.dart
void functionA() { /* ... */ }
void functionB() { /* ... */ }
void functionC() { /* ... */ }
// main.dart
import 'utils.dart' show functionA; // 只导入需要的函数
void main() {
functionA(); // functionB和functionC不会被包含在最终构建中
}
工具与调试
1. Dart Analyzer
# 检查代码质量和导入问题
dart analyze
# 修复自动修复的问题
dart fix --apply
2. 依赖分析
# 查看包依赖树
dart pub deps
# 检查过时的包
dart pub outdated
# 获取依赖
dart pub get
3. IDE支持
大多数IDE提供以下功能:
- 自动导入建议
- 未使用导入检测
- 导入组织和排序
- 跳转到定义
- 查找引用
4. 自定义Lint规则
# analysis_options.yaml
analyzer:
errors:
unused_import: error
depend_on_referenced_packages: error
linter:
rules:
- avoid_empty_else
- prefer_single_quotes
- sort_pub_dependencies
- directives_ordering # 强制导入顺序
5. 导入检查脚本
// check_imports.dart
import 'dart:io';
void main() {
final libDir = Directory('lib');
final files = libDir
.listSync(recursive: true)
.whereType<File>()
.where((f) => f.path.endsWith('.dart'));
for (final file in files) {
final content = file.readAsStringSync();
final lines = content.split('\n');
bool inImportSection = true;
String? lastImportType;
for (int i = 0; i < lines.length; i++) {
final line = lines[i].trim();
if (line.startsWith('import ')) {
final currentType = _getImportType(line);
if (lastImportType != null &&
_shouldComeBefore(lastImportType, currentType)) {
print('❌ 导入顺序错误 in ${file.path}:${i + 1}');
print(' $line');
}
lastImportType = currentType;
} else if (line.isNotEmpty && !line.startsWith('//')) {
inImportSection = false;
break;
}
}
}
}
String _getImportType(String importLine) {
if (importLine.contains("'dart:")) return 'dart';
if (importLine.contains("'package:")) return 'package';
return 'relative';
}
bool _shouldComeBefore(String lastType, String currentType) {
const order = ['dart', 'package', 'relative'];
return order.indexOf(lastType) > order.indexOf(currentType);
}
实用示例集合
1. 多平台条件导入
// platform_service.dart
import 'platform_interface.dart'
if (dart.library.io) 'io_platform_service.dart'
if (dart.library.html) 'web_platform_service.dart';
abstract class PlatformService {
static PlatformService create() => createPlatformService();
Future<String> getPlatformInfo();
Future<void> saveData(String data);
}
// platform_interface.dart
import 'platform_service.dart';
PlatformService createPlatformService() {
throw UnsupportedError('No suitable platform implementation found');
}
// io_platform_service.dart
import 'dart:io';
import 'platform_service.dart';
PlatformService createPlatformService() => IOPlatformService();
class IOPlatformService implements PlatformService {
@override
Future<String> getPlatformInfo() async {
return 'Platform: ${Platform.operatingSystem}';
}
@override
Future<void> saveData(String data) async {
await File('data.txt').writeAsString(data);
}
}
// web_platform_service.dart
import 'dart:html' as html;
import 'platform_service.dart';
PlatformService createPlatformService() => WebPlatformService();
class WebPlatformService implements PlatformService {
@override
Future<String> getPlatformInfo() async {
return 'Browser: ${html.window.navigator.userAgent}';
}
@override
Future<void> saveData(String data) async {
html.window.localStorage['data'] = data;
}
}
2. 插件式架构
// plugin_system.dart
library plugin_system;
export 'src/plugin_interface.dart';
export 'src/plugin_manager.dart';
export 'src/built_in_plugins.dart';
// src/plugin_interface.dart
abstract class Plugin {
String get name;
String get version;
Future<void> initialize();
Future<void> dispose();
}
// src/plugin_manager.dart
class PluginManager {
final Map<String, Plugin> _plugins = {};
Future<void> loadPlugin(Plugin plugin) async {
await plugin.initialize();
_plugins[plugin.name] = plugin;
}
T? getPlugin<T extends Plugin>(String name) {
return _plugins[name] as T?;
}
Future<void> unloadPlugin(String name) async {
final plugin = _plugins.remove(name);
await plugin?.dispose();
}
}
3. 配置系统
// config_system.dart
library config_system;
import 'dart:convert';
import 'dart:io';
class Config {
static Config? _instance;
static Config get instance => _instance ??= Config._();
Config._();
final Map<String, dynamic> _values = {};
Future<void> load(String path) async {
final file = File(path);
if (await file.exists()) {
final content = await file.readAsString();
final data = jsonDecode(content) as Map<String, dynamic>;
_values.addAll(data);
}
}
T get<T>(String key, [T? defaultValue]) {
return _values[key] as T? ?? defaultValue as T;
}
void set<T>(String key, T value) {
_values[key] = value;
}
Future<void> save(String path) async {
final file = File(path);
await file.writeAsString(jsonEncode(_values));
}
}
// 使用示例
Future<void> main() async {
final config = Config.instance;
await config.load('config.json');
final apiUrl = config.get<String>('api_url', 'https://api.example.com');
final timeout = config.get<int>('timeout', 30);
print('API URL: $apiUrl');
print('Timeout: ${timeout}s');
}
总结
Dart的库和导入系统是构建大型、可维护应用程序的基础。通过合理使用:
- 导入机制:组织和重用代码
- 导出机制:创建清晰的API
- 可见性控制:实现良好的封装
- 条件导入:支持多平台开发
- 延迟加载:优化应用性能
遵循最佳实践,可以创建出结构清晰、性能优良的Dart应用程序。
关键要点
- 保持导入有序:dart → package → relative
- 合理使用前缀:解决命名冲突
- 善用选择性导入:减少命名空间污染
- 正确封装私有成员:提供清晰的公共API
- 文档化公共接口:提高代码可维护性
- 考虑性能影响:使用延迟加载等优化技术
推荐资源
这份指南涵盖了Dart库和导入的所有重要方面,从基础概念到高级技巧,旨在帮助开发者编写更好的Dart代码。