dart笔记Dart 库
1. 了解Dart的库
1.1 Dart库的概念
Dart库是一种用于组织和管理Dart代码的结构化方式。它可以将相关的功能和类封装在一起,提供了代码复用、模块化和可维护性的好处。库可以包含一组相关的函数、类、变量和其他代码元素,并且可以被其他Dart程序引用和使用。
库的使用有助于将代码分离为逻辑上独立的模块,从而使代码更易于理解和维护。它们还提供了命名空间管理,避免了命名冲突和代码混乱的问题。Dart库可以包含公共的API接口,使其可供其他开发人员在其项目中使用。
1.2 Dart 库的结构
Dart库的结构由以下组成部分构成:
1.2.1 导入其他库
使用import
关键字可以引入其他Dart库。通过导入其他库,可以在当前库中使用被导入库的功能和类。例如:
import 'package:my_library/my_library.dart';
1.2.2 声明库
在Dart库中,可以使用library
关键字来声明库的名称和特性。这个声明通常位于库的文件的顶部。例如:
library my_library;
库的名称通常采用小写字母和下划线的命名规范。
1.2.3 导出公共API
使用export
关键字可以将当前库中的公共API导出给其他库使用。这样可以控制哪些部分对外可见,哪些部分仅限于当前库内部使用。例如:
export 'src/my_class.dart'; export 'src/my_functions.dart';
1.2.4 定义部分
Dart库可以由多个文件组成,这些文件一起构成了库的定义部分。通过将相关的代码组织在不同的文件中,可以更好地管理和维护代码。每个文件都可以包含类、函数、变量等。例如:
my_library.dart
:库的入口文件,可以导入其他文件和声明库的特性。src/my_class.dart
:包含一个类的定义。src/my_functions.dart
:包含一组相关的函数定义。
1.2.5 访问修饰符
Dart 库中的代码可以使用访问修饰符来控制其可见性。public
修饰符表示对外可见,private
修饰符表示仅限于当前库内部可见。默认情况下,库中的成员都是公共的,可以被其他库引用和使用。
例如,使用下划线作为标识符前缀可以将其标记为私有成员,如_privateFunction()
。
以上是关于Dart库的概念和结构的基本介绍。使用库可以提高代码
的可重用性和可维护性,同时也提供了更好的代码组织和管理方式。
1.3 如何创建一个Dart库
要创建一个Dart库,可以按照以下步骤进行操作:
1.3.1 创建新的Dart项目
首先,创建一个用于存放库代码的文件夹。可以选择一个合适的位置,并为该文件夹选择一个有意义的名称,通常使用小写字母和下划线进行命名,比如在项目根目录下创建一个名为my_library
的文件夹。
接着,在库文件夹中创建一个Dart文件,用于作为库的入口文件。这个文件将包含库的导入语句、声明以及对其他文件的引用。
1.3.2 声明库名称
在入口文件中使用library
关键字来声明库的名称和特性。这个声明通常位于文件的顶部。比如,在my_library.dart
文件中添加以下代码:
library my_library;
1.3.3 创建库的其他文件
根据需要,可以在库文件夹中创建多个Dart文件,用于组织和管理库中的功能和类。这些文件可以按照自己的逻辑进行命名,并根据需要创建子文件夹来组织文件结构。
例如,在my_library
文件夹中创建一个名为src
的子文件夹,并在其中创建my_class.dart
和my_functions.dart
文件。
1.3.4 编写库的代码
在库文件和其他文件中编写代码,包括定义类、函数、变量等。
例如,在my_class.dart
文件中添加以下代码:
class MyClass { // 类的定义 }
在my_functions.dart
文件中添加以下代码:
void myFunction() { // 函数的定义 }
1.3.5 导出公共API
如果希望将库的某些部分暴露给其他库使用,可以使用export
关键字来导出公共API。这样可以控制库中哪些部分对外可见。
例如,在入口文件my_library.dart
中添加以下代码:
export 'src/my_class.dart'; export 'src/my_functions.dart';
1.3.6 使用库
要在其他Dart程序中使用创建的库,可以使用import
关键字来导入该库。
例如,在另一个Dart文件中使用my_library
库:
import 'package:my_library/my_library.dart'; void main() { var obj = MyClass(); // 使用库中的功能和类 }
通过按照以上步骤创建和组织Dart库,可以实现代码的模块化、重用和易维护性,提高开发效率并促进团队协作。
2 Dart库的导入
2.1 使用import导入一个库
在Dart中,可以使用import
关键字来导入一个库,以便在当前文件中使用该库的功能和类。导入库的语法如下:
import 'package:library_name/library_file.dart';
其中,library_name
是要导入的库的名称,library_file.dart
是库的入口文件。
例如,导入名为my_library
的库:
import 'package:my_library/my_library.dart';
一旦导入了库,就可以使用库中公开的API来调用函数、创建对象等。
2.2 使用as对导入库提供别名
在某些情况下,为了避免命名冲突或简化代码,可以为导入的库提供一个别名。使用as
关键字可以为库提供别名,以便在代码中使用。
例如,给导入的my_library
库提供一个别名ml
:
import 'package:my_library/my_library.dart' as ml;
现在,可以使用别名ml
来引用库中的类和函数:
void main() { var obj = ml.MyClass(); ml.myFunction(); }
2.3 使用show和hide控制导入库成员的可见性
有时,导入的库可能包含大量的成员,但只需要使用其中的一部分。在这种情况下,可以使用show
和hide
关键字来控制导入的库成员的可见性。
- 使用
show
关键字可以只导入指定的成员,其他成员将不可见。 - 使用
hide
关键字可以隐藏指定的成员,其他成员仍然可见。
例如,只导入my_library
库中的MyClass
类和myFunction
函数:
import 'package:my_library/my_library.dart' show MyClass, myFunction;
或者,导入my_library
库的所有成员,但隐藏privateFunction
函数:
import 'package:my_library/my_library.dart' hide privateFunction;
通过使用show
和hide
关键字,可以精确地控制导入的库成员的可见性,避免不必要的冲突和混乱。
在Dart中,库的导入使得代码的组织和管理变得更加灵活和可靠。通过使用别名、show和hide,可以更好地控制库的使用方式,并确保代码的可读性和可维护性。
3. Dart库的分区
3.1 使用part和part of关键字进行代码拆分
在Dart中,使用part
和part of
关键字可以将一个库拆分为多个文件,这些文件被称为分区。通过分区,可以将相关的代码组织在一起,使得代码更具可读性、可维护性和可重用性。
下面是使用part
和part of
进行代码拆分的示例:
假设有一个名为my_library.dart
的库文件,包含以下代码:
library my_library; part 'my_class.dart'; part 'my_functions.dart'; // 在此处定义其他部分的代码
在同一个目录下,创建两个分区文件my_class.dart
和my_functions.dart
,分别包含库中的类和函数的定义。
my_class.dart
文件的内容如下:
part of my_library; class MyClass { // 类的定义 }
my_functions.dart
文件的内容如下:
part of my_library; void myFunction() { // 函数的定义 }
通过使用part
关键字将这两个文件与主库文件my_library.dart
关联起来,并使用part of
关键字声明它们属于哪个库,可以实现代码的拆分和组合。
3.2 Dart库分区的应用场景和优缺点
使用Dart库分区的方式可以带来一些好处,但也需要注意一些限制。下面是库分区的一些应用场景、优点和缺点:
应用场景:
- 拆分大型库:当库变得庞大复杂时,可以使用分区将代码逻辑上分组,提高代码的可读性和可维护性。
- 模块化开发:库分区可以帮助多个开发人员同时工作,每个人负责不同的分区,最后将它们组合在一起。
- 代码共享:可以将分区作为可重用的代码模块,供其他库或项目使用。
优点:
- 代码组织和可读性:库分区将相关的代码组织在一起,使得代码结构清晰,易于理解和维护。
- 分工协作:多人协作开发时,可以并行地修改不同的分区,减少代码冲突和协作成本。
- 代码复用:库的分区可以作为可重用的代码模块,提供了更高的代码复用性。
缺点:
- 过度拆分:如果分区划分得过于细化,可能会导致代码过于分散,增加代码的复杂性。
- 跨文件依赖:分区之间可能存在相互依赖关系,需要谨慎管理,避免出现循环依赖等问题。
使用库分区时,需要注意合理划分分区
的粒度,避免过度拆分和复杂性增加。合理使用库分区可以提高代码的可维护性、可读性和可重用性,使代码更易于开发和维护。
3.3 Dart 库应用案例
以下是一个具体的实战应用案例,展示了如何使用Dart库分区来组织和管理代码。本案例中假设我们正在开发一个图形处理库,其中包含了各种图形对象和操作。我们可以将库分为以下几个分区:
shapes.dart
分区:这个分区包含了图形对象的定义,如Circle
、Rectangle
等类的定义。
part of graphics_library; class Circle { // ... } class Rectangle { // ... }
operations.dart
分区:这个分区包含了图形操作的定义,如计算面积、计算周长等函数的定义。
part of graphics_library; double calculateArea(Shape shape) { // ... } double calculatePerimeter(Shape shape) { // ... }
utilities.dart
分区:这个分区包含了一些辅助函数和工具函数的定义,如计算两点之间距离、检测点是否在图形内等函数的定义。
part of graphics_library; double calculateDistance(Point p1, Point p2) { // ... } bool isPointInsideShape(Point point, Shape shape) { // ... }
在主库文件graphics_library.dart
中,我们使用part
关键字将这些分区文件关联起来。
library graphics_library; part 'shapes.dart'; part 'operations.dart'; part 'utilities.dart'; // 在此处可以编写库的其他代码
这样,我们就成功地将库代码分割成了多个分区,每个分区负责不同的功能和模块。这种方式使得代码的组织和管理更加清晰和灵活。
使用该图形处理库时,可以按需导入所需的分区,例如:
import 'package:graphics_library/graphics_library.dart'; import 'package:graphics_library/operations.dart'; void main() { var circle = Circle(radius: 5); var area = calculateArea(circle); print('The area of the circle is $area'); }
通过使用库分区,我们可以实现模块化开发,将不同功能和模块的代码分别放置在不同的文件中,提高代码的可读性、可维护性和可重用性。同时,库分区也使得多人协作开发更加高效,并提供了更好的代码组织和管理方式。
4. Dart Packages和Pub工具
4.1 什么是Dart Packages
在Dart中,Package是指一组相关的Dart库和资源的集合,用于共享和发布可重用的代码。一个Dart Package通常包含一个或多个库文件以及其他相关的资源,如配置文件、文档、测试代码等。
Dart Packages提供了一种机制来组织、共享和管理代码,使得开发人员可以更轻松地构建和使用可重用的代码模块。
4.2 如何使用Pub创建一个新的Dart Packages
Pub是Dart的官方包管理工具,用于创建、发布和管理Dart Packages。通过Pub,可以快速创建一个新的Dart Package,并为其添加所需的功能和依赖关系。
以下是使用Pub创建一个新的Dart Package的步骤:
4.2.1 创建和初始化一个新的 Dart Package
在项目所在的目录下创建一个新的文件夹,用于存放Dart Package的代码和资源。可以选择一个合适的名称,通常使用小写字母和下划线进行命名,例如,在项目根目录下创建一个名为my_package
的文件夹。
接着,在终端中进入到新创建的包文件夹my_package
,然后运行以下命令来初始化 Dart Package:
dart pub init
这个命令将会在包文件夹中生成一个pubspec.yaml
文件,该文件用于描述包的信息和依赖关系。
4.2.2 编辑 pubspec.yaml 文件
打开生成的pubspec.yaml
文件,并根据需要编辑其中的内容。
在pubspec.yaml
文件中,可以设置包的名称、版本号、作者信息,以及声明包的依赖关系等。
例如:
name: my_package version: 1.0.0 description: A Dart package example author: Your Name
4.2.3 添加库文件和资源
在包文件夹中创建一个或多个Dart库文件,并在pubspec.yaml
文件中声明这些库文件。
例如,在lib
文件夹中创建一个名为my_library.dart
的库文件,并在pubspec.yaml
文件中添加以下代码:
... flutter: sdk: flutter # Add the path to your library file library: - lib/my_library.dart ...
4.2.4 安装依赖
如果你的包依赖于其他的Dart Packages,可以在pubspec.yaml
文件中的dependencies
部分添加这些依赖关系,并运行以下命令来安装依赖:
dart pub get
Pub将会根据pubspec.yaml
文件中声明的依赖关系,自动下载并安装所需的依赖包。
4.2.5 使用Dart Package
要在其他Dart项目中使用你的包,可以使用import
关键字来导入你的库
文件。
例如,在其他Dart项目的文件中,可以添加以下导入语句来使用my_package
包中的库:
import 'package:my_package/my_library.dart';
通过上述步骤,你已成功地创建了一个新的Dart Package,并使用Pub工具进行了初始化、依赖管理和使用。
Pub工具为我们提供了方便的方式来创建、发布和管理Dart Packages,使得代码的共享和重用变得更加简单和高效。
4.3 如何在项目中使用第三方Dart Packages
在Dart中,可以使用第三方的Dart Packages来扩展和增强项目的功能。Pub工具提供了便捷的方式来引入和使用第三方包。
以下是在项目中使用第三方Dart Packages的步骤:
4.3.1 在pubspec.yaml文件中声明依赖关系
在项目的pubspec.yaml
文件中的dependencies
部分,添加第三方包的名称和版本信息。
例如,假设要使用dio
包,可以在pubspec.yaml
文件中添加以下内容:
dependencies: dio: ^5.2.1+1
在这个例子中,我们添加了对dio
包的依赖,并指定了最低版本要求为5.2.1+1
。
4.3.2 安装依赖
运行以下命令来安装项目的依赖:
dart pub get
Pub工具将会根据pubspec.yaml
文件中声明的依赖关系,自动下载并安装所需的第三方包。
4.3.3 导入并使用第三方包
在需要使用第三方包的Dart文件中,使用import
关键字导入该包的库文件。
例如,假设我们想在项目中使用dio
包的功能,可以在Dart文件中添加以下导入语句:
import 'package:dio/dio.dart' as dio;
然后,就可以使用dio
包中的类和函数了。例如:
void main() async { final dioInstance = dio.Dio(); final response = await dioInstance.get('https://pub.dev'); print(response.data); }
通过上述步骤,我们成功地引入了第三方Dart Package,并在项目中使用了该包提供的功能。
使用第三方Dart Packages可以大大简化开发过程,减少重复编写代码的工作量。Pub工具使得依赖管理和包的使用变得更加方便和高效,提供了丰富的开源库供开发者使用。
4.4 发布自己的Dart Packages
Pub工具提供了方便的方式来发布自己的Dart Packages,使其可以供他人使用。以下是发布自己的Dart Packages的步骤:
4.4.1 更新 pubspec.yaml 文件
在准备发布之前,确保你的 pubspec.yaml
文件中包含了正确的包信息和依赖关系。
- 确保包的名称、版本号、描述等信息正确。
- 检查并更新包的依赖关系,确保列出了所有必要的依赖项。
4.4.2 注册一个Pub.dev 账号
在发布之前,你需要注册一个 Pub.dev 账号。Pub.dev 是 Dart 社区的官方包托管平台,用于发布和共享 Dart Packages。
访问 https://pub.dev 并按照指示注册一个账号,如已经注册直接登陆即可:
4.4.3 打包并发布
在终端中进入到包的根目录,并运行以下命令来打包和发布你的包:
dart pub publish
该命令将会自动执行以下操作:
Pub工具会提示你登录你的 Pub.dev 账号,以便将包发布到你的账号下。
4.4.4 版本管理
在每次发布包之前,需要管理好包的版本号。Dart 使用 语义化版本号(Semantic Versioning)来管理包的版本。
根据语义化版本号规范,每次发布包时,可以根据修改的内容和功能更新级别来决定版本号的递增方式:
项目 | 描述 |
主版本号(Major version) | 当你进行不兼容的 API 修改时,递增主版本号。 |
次版本号(Minor version) | 当你添加了向后兼容的功能时,递增次版本号。 |
补丁版本号(Patch version) | 当你进行向后兼容的错误修复时,递增补丁版本号。 |
通过正确管理版本号,可以确保包的使用者能够根据版本号来确定包的更新和向后兼容性。通过以上步骤,你已成功地发布了自己的Dart Package,使其可以供其他开发者使用。
5. 库的命名与拆分
在Dart中,库的命名和拆分对于代码的组织和可维护性非常重要。良好的库命名和合理的库拆分可以提高代码的可读性、可复用性和可维护性。下面介绍几个关于库的命名和拆分的注意事项:
5.1 库的命名
在命名库时,应遵循一些命名规范和最佳实践:
- 库名应该具有 描述性,能够 准确反映库所提供的功能。
- 库名遵循 小写下划线命名法(lowercase_with_underscores),采用 小写字母,使用 下划线来分隔单词。
- 库名 不应 包含特殊字符、空格或连字符。
- 库名应该是 唯一的,避免与其他库重名。
良好的库命名可以提高代码的可读性和可维护性,使其他开发者能够更好地理解库的用途和功能。
5.2 库的拆分
库的拆分可以将代码按照功能或模块进行组织,使得代码结构更清晰,提高代码的可复用性和可维护性。
关于代码的拆分并没有强制性的要求,但是通常多数开发者有达成默契的地方,比如以下就是 dart 库拆分的常见参考依据:
项目 | 描述 |
根据功能拆分 | 将相关的功能放在同一个库中,这样可以使代码更具有内聚性和可重用性。 |
使用 part 和 part of 关键字进行拆分 |
Dart提供了part和part of关键字,可以将一个库拆分成多个部分,每个部分可以分别位于不同的文件中,但是它们共享相同的库范围。 |
拆分出通用组件 | 将通用的组件拆分成独立的库,可以在不同的项目中重复使用,提高代码的可复用性。 |
拆分出工具类库 | 将一些常用的工具类或辅助函数拆分成独立的库,可以在不同的项目中共享,避免重复编写相似的代码。 |
虽然以上这些代码的拆分的依据并不是强制性的,但是库的合理拆分可以降低代码的耦合度,提高代码的可维护性和可测试性。同时有助于其他开发者理解和使用你的代码。
5.3 小结
Dart 库的命名和拆分是代码组织和管理的重要方面。通过良好的库命名和合理的库拆分,可以提高代码的可读性、可复用性和可维护性。合理使用 as
、show
、hide
等关键字,可以解决库重名和冲突的问题。同时,通过使用 part
和part of
关键字,可以将库拆分成多个部分,更好地组
织和管理代码。
通过遵循命名规范、合理拆分库以及充分利用 Dart 语言的特性,我们可以创建出高质量、可维护的库,提高开发效率和代码质量。
6. 库的导出
在 Dart 中,库导出允许我们将一个库中的一部分或全部内容导出给其他库使用。通过库的导出,我们可以提供一个统一的接口,让其他开发者可以方便地访问和使用我们的库。
库导出的语法如下:
export 'library.dart';
在上述语法中,library.dart
是要导出的库文件名。我们可以选择性地导出库中的一部分内容,也可以导出整个库。
以下是一些关于库导出的使用场景和注意事项:
6.1 导出整个库
如果我们希望将整个库导出给其他库使用,可以直接在库文件中使用导出语句:
export 'package:my_package/my_library.dart';
通过上述导出语句,其他库就可以引入我们的库,并访问其中的所有公开成员。
6.2 导出部分内容(show
关键字)
有时候,我们可能只希望导出库中的部分内容,而不是全部内容。可以使用show
关键字来指定要导出的成员:
export 'package:my_package/my_library.dart' show MyClass, myFunction;
上述代码中,只导出了 MyClass
类 和 myFunction
函数,其他成员将不可见。
6.3 重命名导出
在导出库时,我们也可以给导出的成员提供别名,以避免与当前库中的成员冲突。可以使用 as
关键字来为导出的成员提供别名:
export 'package:my_package/my_library.dart' as mylib;
上述代码中,我们将package:my_package/my_library.dart
导出为mylib
,其他库就可以使用mylib
作为别名来访问导出的成员。
6.4 多个库文件导出
我们也可以在一个库中同时导出多个库文件,以提供更灵活的库组织结构。可以在导出语句中使用逗号分隔多个文件:
export 'package:my_package/file1.dart', 'package:my_package/file2.dart';
通过上述代码,我们可以同时将 file1.dart
和 file2.dart
导出给其他库使用。
6.5 避免循环导出
在使用库导出时,需要注意避免循环导出的情况。循环导出指的是两个或多个库相互导出对方,形成了循环的依赖关系。
循环导出会导致编译器报错,并可能引发其他问题。为了避免循环导出,需要仔细规划库之间的依赖关系,确保导出的层次结构合理且不存在循环引用。
库导出是Dart中重要的组织和封装机制之一,能够帮助我们构建可复用、可扩展的代码库。通过合理使用库导出,我们可以提供清晰的接口,减少代码冗余,提高代码的可读性和可维护性。
7. 库重名与冲突解决
在Dart开发中,可能会遇到库重名的情况,即引入的不同库具有相同的名称。这种情况会导致编译器无法确定要使用的是哪个库,从而产生冲突。为了解决库重名的问题,可以采取以下方法:
7.1 使用as
关键字给库提供别名
可以使用as关键字给导入的库提供别名,以便在代码中明确指定要使用的库。这样可以避免库重名造成的冲突。
例如,假设我们同时引入了两个具有相同名称的库:
import 'package:my_package/my_library.dart'; import 'package:other_package/my_library.dart';
为了避免冲突,可以为其中一个库提供别名:
import 'package:my_package/my_library.dart'; import 'package:other_package/my_library.dart' as other;
现在,我们可以通过别名来指定要使用的库:
my_library.someFunction(); // 使用my_package中的库函数 other.someFunction(); // 使用other_package中的库函数
通过给库提供别名,我们可以明确指定要使用的库,从而解决库重名的冲突。
7.2 使用 show
和 hide
控制导入库成员的可见性
除了给库提供别名外,还可以使用 show
和 hide
关键字来控制导入库的成员可见性。通过这种方式,可以只导入需要使用的成员,避免导入整个库。
import 'package:my_package/my_library.dart' show MyClass;
上述代码中,只导入了my_library库中的 MyClass 类,其他成员不可见。
import 'package:my_package/my_library.dart' hide SomeClass;
上述代码中,导入了my_library 库中除了 SomeClass 类之外的所有成员。
通过使用 show
和 hide
关键字,我们可以更加精确地控制导入的成员,避免冲突和不必要的引入。
通过以上方法,我们可以解决库重名的问题,并确保在代码中能够准确地引用和使用所需的库成员,提高代码的可读性和维护性。