# Dart教程 - 10 库的使用
前面在学习Dart的时候,基本所有的代码都是写在一个dart文件中,最多也只是简单的使用了import关键字,引入了其他的dart文件。在实际的开发中,代码量是很大的,所以会编写很多的dart文件,通过使用库管理,我们可以更好将相关的功能或类组织在一起,以便更好地维护和复用代码。同时我们可以引入一些内置的或第三方编写的库文件,提高开发效率,避免重复造轮子。
Dart中的库主要有三种:
系统内置的库
自定义的库
Pub包管理系统中的库
# 10.1 系统内置库
Dart 自带了一些常用的内置库,引入内置库的方式:
import 'dart:库名';
举个栗子:
比如我们进行数学运算,进行开根号运算:
import 'dart:math';
void main() {
double result = sqrt(4); // 开根号运算
print(result);
int maxNum = max(3, 5); // 求较大的数
print(maxNum);
}
2
3
4
5
6
7
8
9
上面我们使用 import 'dart:math';
引入了 math
内置库,并使用了内置库中的开根号运算函数sqrt
和求较大值的函数max
。
其实dart默认是导入了 dart:core
库的, dart:core
是 Dart 的核心库,包含了 Dart 的基本数据类型、集合类型、函数和异常处理等基本功能,在编码的时候无需显式导入即可使用。
举个栗子:
void main() {
// 使用 dart:core 中的 print 函数
print('Hello, Dart!');
// 使用 dart:core 中的 List 类型
var myList = [1, 2, 3];
print(myList); // 输出:[1, 2, 3]
}
2
3
4
5
6
7
8
上面使用了print函数、列表,这些都是 dart:core
库中的,该库默认是导入的,不需要手动导入。
# 10.2 自定义的库
前面也已经使用了自定义库的导入,引入自定义库的方式:
import '目录名/文件名.dart'
举个栗子:
定义了一个Person.dart
class Person {
String name;
int age;
Person(this.name, this.age);
}
2
3
4
5
6
7
定义了一个StrUtils.dart
class StrUtils {
// 判断字符串是否为空
static bool isEmpty(String? str) {
return str == null || str.trim().isEmpty;
}
// 判断字符串是否不为空
static bool isNotEmpty(String? str) {
return !isEmpty(str);
}
// 去除字符串首尾空格
static String trim(String? str) {
return str?.trim() ?? '';
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
然后在main.dart中引入上面的两个dart文件。
Main.dart
import 'domain/Person.dart';
import 'util/StrUtils.dart';
import 'Test.dart';
void main() {
Person person = Person("逗比", 12);
print(StrUtils.isEmpty(person.name));
Test test = new Test();
}
2
3
4
5
6
7
8
9
10
如果要引入的dart文件在当前目录,直接写文件名 Test.dart
即可。
# 10.3 Pub包管理系统中的库
pub
包管理系统是官方的包管理工具,用于查找、安装和发布 Dart 包。这个系统允许开发者将自己编写的代码封装成包,供其他开发者在自己的项目中使用,也可以方便地使用其他开发者分享的包来扩展自己的项目功能。
一般情况下,我们都是在自己的项目中集成其他人开发的包,来提高我们的开发效率。
我们可以通过如下地址查找库:
https://pub.dev/packages
或
https://pub-web.flutter-io.cn/packages
2
3
使用Pub包管理系统,需要一下几个步骤:
- 首先可以在上面的网页中查找自己需要的库;
- 需要在自己的项目根目录创建一个
pubspec.yaml
文件;在pubspec.yaml
文件中,配置依赖的库的信息,包括名称、版本、描述等; - 然后在根目录下运行
dart pub get
命令,将库下载到本地; - 然后就可以在代码中引入库中的功能了。
举个栗子:
我们想发起http请求,需要使用Pub包管理系统中http库。
# 1 查找库
我们可以在上面地址的网页中查找到http库
在库的详情页,我们可以看到库的安装方式:
我们使用 pubspec.yaml
文件安装即可。
# 2 新建 pubspec.yaml 文件
在项目根目录下新建 pubspec.yaml
文件,内容如下:
name: hello_dart # 项目名称
description: My Dart application # 项目描述
version: 1.0.0 # 项目版本
environment: # 指定sdk版本约束
sdk: '>=2.12.0 <3.0.0'
dependencies:
http: ^0.13.6
dev_dependencies:
# 添加开发时需要的依赖包,如果有的话
2
3
4
5
6
7
8
9
10
11
12
13
有的依赖对SDK版本有要求,例如当dart版本是3.0以下是,引入http1.0.0就会有如下错误:
Because hello_dart depends on http >=1.0.0 which requires SDK version >=3.0.0 <4.0.0, version solving failed.
# 3 下载依赖
在上面保存 pubspec.yaml
文件的时候,VSCode就会自动下载依赖。
我们也可以在根目录下运行 dart pub get
命令来下载依赖;
# 4 引入和使用依赖
下载依赖后,就可以引入依赖并使用了,举个栗子:
import 'dart:convert' as convert;
import 'package:http/http.dart';
void main(List<String> arguments) async {
var url = Uri.http('www.doubibiji.com', '/apis/category/allNoteList', {});
var response = await get(url);
if (response.statusCode == 200) {
var jsonResponse =
convert.jsonDecode(response.body) as Map<String, dynamic>;
print('http result: $jsonResponse');
} else {
print('Request failed with status: ${response.statusCode}.');
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在上面的代码中使用 import 'package:http/http.dart';
引入了http。
其中的函数 get(url)
就是http提供的,用于发起 get 请求。
关于 await
的使用,后面讲异步的时候再讲解,这里知道它在等待请求的信息即可。
# 10.4 库名冲突
如果我们引入的多个库存在相同名称的内容的时候,我们可以使用 as 关键字
来避免冲突。
举个栗子:
我们在两个包下都有Person.dart,然后如何在Main.dart同时引入两个Person类呢?
Main.dart
import 'domain/Person.dart' as Per1;
import 'pojo/Person.dart' as Per2;
void main(List<String> args) {
Per1.Person p1 = Per1.Person("Doubi", 12);
Per2.Person p2 = Per2.Person("Niubi", 13);
}
2
3
4
5
6
7
我们可以在引入的时候使用 as
起别名,然后在使用的时候,在前面添加别名。
在上面我们使用http请求的时候,一般也是会起个别名,防止冲突:
// 引入的时候使用别名,防止冲突
import 'package:http/http.dart' as http;
// 然后使用http.get()
var response = await http.get(url);
2
3
4
# 10.5 部分导入
如果希望只导入库中某些内容,我们可以使用 show
和 hide
关键字。
- show关键字: 只导入需要的部分
- **hide关键字:**隐藏不需要的部分
举个栗子:
在http库中,提供了 get
和 post
方法,如下:
import 'package:http/http.dart' as http;
void main(List<String> arguments) async {
var url = Uri.http('www.doubibiji.com', '/apis/category/allNoteList', {});
var response1 = await http.get(url);
var response2 = await http.post(url);
}
2
3
4
5
6
7
8
我们可以只导入 get 函数:
import 'package:http/http.dart' as http show get;
这样 http.post(url);
将会报错。
也可以隐藏 get 函数:
import 'package:http/http.dart' as http hide get;
这样将不会导入 get 函数,http.get(url);
将会报错。
# 10.6 库的定义
在开发中,如果一个库文件太大,将所有内容保存到一个文件中是不太合理的,我们有可能希望将这个库进行拆分,每个文件都包含库中的一部分代码,这样可以更好地组织和管理大型项目中的代码。
在之前我们可以使用part
关键字,但是现在不推荐了,替代方案是使用export。
举个栗子:
我们现在有一个库,utils.dart
// utils.dart
int add(int a, int b) {
return a + b;
}
class Point {
int x;
int y;
Point(this.x, this.y);
}
2
3
4
5
6
7
8
9
10
11
12
现在我们想将上面的库拆分成多个文件,将 add()
函数和 Point
定义到不同的dart文件中。
于是创建了 math_utils.dart
,将 add()
函数定义到其中:
// math_utils.dart
int add(int a, int b) {
return a + b;
}
2
3
4
5
继续,创建了 geometry_utils.dart
,将 Point
定义到其中:
// geometry_utils.dart
class Point {
int x;
int y;
Point(this.x, this.y);
}
2
3
4
5
6
7
8
现在已经将 utils.dart
库中的内容分到两个文件中了,现在需要使用 export
关键字将这两个文件中的公共部分暴露给其他库,编辑 utils.dart
为:
// utils.dart
library my_utils;
export 'math_utils.dart';
export 'geometry_utils.dart';
2
3
4
5
6
我们现在在 utils.dart
中,将 math_utils.dart
和 geometry_utils.dart
导出,然后使用 library
关键字定义库的名称。
library
关键字的作用主要是为了将多个相关的 .dart
文件组织为一个库。在大多数情况下,特别是在简单的项目中或者所有相关文件都在同一个文件夹下时,library
关键字是可选的,不写也不会产生影响。所以上面 library my_utils;
这句代码,不写也没有影响。
现在编写 Main.dart
,在 Main.dart
中引入和使用 utils.dart
:
// main.dart
import 'lib/utils.dart';
void main() {
int result = add(3, 5);
print('The sum is: $result');
Point point = Point(10, 20);
print('Point: (${point.x}, ${point.y})');
}
2
3
4
5
6
7
8
9
10
通过 library
和 export
可以将库拆分成多个文件,每个文件包含库中的一部分代码,以实现更好的代码组织和管理。
上面的代码结构如下: