dart笔记:Dart 库

dart笔记
Dart 库

- 文章信息 -
Author: Jack Lee (jcLee95)
Visit me at: https://jclee95.blog.csdn.net
Email: [email protected].
Shenzhen China
Address of this article:https://blog.csdn.net/qq_28550263/article/details/131506108

【介绍】:本文介绍 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.dartmy_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控制导入库成员的可见性

有时,导入的库可能包含大量的成员,但只需要使用其中的一部分。在这种情况下,可以使用showhide关键字来控制导入的库成员的可见性。

  • 使用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;

通过使用showhide关键字,可以精确地控制导入的库成员的可见性,避免不必要的冲突和混乱。

在Dart中,库的导入使得代码的组织和管理变得更加灵活和可靠。通过使用别名、show和hide,可以更好地控制库的使用方式,并确保代码的可读性和可维护性。

3. Dart库的分区

3.1 使用part和part of关键字进行代码拆分

在Dart中,使用partpart of关键字可以将一个库拆分为多个文件,这些文件被称为分区。通过分区,可以将相关的代码组织在一起,使得代码更具可读性、可维护性和可重用性。

下面是使用partpart of进行代码拆分的示例:

假设有一个名为my_library.dart的库文件,包含以下代码:

library my_library;

part 'my_class.dart';
part 'my_functions.dart';

// 在此处定义其他部分的代码

在同一个目录下,创建两个分区文件my_class.dartmy_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库分区来组织和管理代码。本案例中假设我们正在开发一个图形处理库,其中包含了各种图形对象和操作。我们可以将库分为以下几个分区:

  1. shapes.dart 分区:这个分区包含了图形对象的定义,如CircleRectangle等类的定义。
part of graphics_library;

class Circle {
    
    
  // ...
}

class Rectangle {
    
    
  // ...
}
  1. operations.dart 分区:这个分区包含了图形操作的定义,如计算面积、计算周长等函数的定义。
part of graphics_library;

double calculateArea(Shape shape) {
    
    
  // ...
}

double calculatePerimeter(Shape shape) {
    
    
  // ...
}
  1. 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.devDart 社区的官方包托管平台,用于发布和共享 Dart Packages。

在这里插入图片描述

访问 https://pub.dev 并按照指示注册一个账号,如已经注册直接登陆即可:

在这里插入图片描述

4.4.3 打包并发布

在终端中进入到包的根目录,并运行以下命令来打包和发布你的包:

dart pub publish

该命令将会自动执行以下操作:

  1. 检查并验证包的完整性和规范性。
  2. 打包并上传你的包到 Pub.dev
  3. 将包的版本信息发布到 Pub.dev

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 库拆分的常见参考依据:

项目 描述
根据功能拆分 将相关的功能放在同一个库中,这样可以使代码更具有内聚性和可重用性。
使用 partpart of 关键字进行拆分 Dart提供了part和part of关键字,可以将一个库拆分成多个部分,每个部分可以分别位于不同的文件中,但是它们共享相同的库范围。
拆分出通用组件 将通用的组件拆分成独立的库,可以在不同的项目中重复使用,提高代码的可复用性。
拆分出工具类库 将一些常用的工具类或辅助函数拆分成独立的库,可以在不同的项目中共享,避免重复编写相似的代码。

虽然以上这些代码的拆分的依据并不是强制性的,但是库的合理拆分可以降低代码的耦合度,提高代码的可维护性和可测试性。同时有助于其他开发者理解和使用你的代码。

5.3 小结

Dart 库的命名和拆分是代码组织和管理的重要方面。通过良好的库命名和合理的库拆分,可以提高代码的可读性、可复用性和可维护性。合理使用 asshowhide等关键字,可以解决库重名和冲突的问题。同时,通过使用 partpart 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.dartfile2.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 使用 showhide 控制导入库成员的可见性

除了给库提供别名外,还可以使用 showhide 关键字来控制导入库的成员可见性。通过这种方式,可以只导入需要使用的成员,避免导入整个库。

import 'package:my_package/my_library.dart' show MyClass;

上述代码中,只导入了my_library库中的 MyClass 类,其他成员不可见。

import 'package:my_package/my_library.dart' hide SomeClass;

上述代码中,导入了my_library 库中除了 SomeClass 类之外的所有成员。

通过使用 showhide 关键字,我们可以更加精确地控制导入的成员,避免冲突和不必要的引入。

通过以上方法,我们可以解决库重名的问题,并确保在代码中能够准确地引用和使用所需的库成员,提高代码的可读性和维护性。

猜你喜欢

转载自blog.csdn.net/qq_28550263/article/details/131506108