Sway 库(Library)完全指南:从代码复用到内外部库的导入与部署
【免费下载链接】sway🌴 Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway
本篇技术指南聚焦 Sway 语言中的程序类型之一——库(Library),系统讲解如何用library关键字组织可复用代码、通过pub关键字控制可见性,以及如何将库区分为项目内部(Internal)与外部(External)两种形态并完成依赖声明与导入。读完本文,你将掌握在 Fuel 生态的 Sway 项目中拆分公共逻辑、管理库依赖、规避代码重复的完整实战方案。
什么是 Sway 库
在 Sway 中,库(Library)是一种用于承载"执行常见操作"的代码的程序类型,其根本目的是防止代码重复(code duplication)。当多个合约、脚本或谓词需要共享同一段逻辑(例如数学计算、地址校验、存储封装)时,将其抽取到库中,即可在多个程序文件之间复用。
从仓库的官方标准库可以看到这种组织方式的直接体现:sway-lib-std/src/lib.sw 正是以library;声明开头的库文件,其内部又通过pub mod暴露了marker、registers、flags、ops、vec等数十个公开模块,整个std标准库本质上就是一个大型 Sway 库。
库的定义
库通过在文件开头使用library关键字来定义。一个最基本的库文件如下:
library;与合约、脚本、谓词等程序类型不同,库文件没有main函数入口,它只负责向其他代码提供声明。
仓库中的示例库位于 docs/reference/src/code/language/program-types/libraries/internal/my_lib/src/my_library.sw,完整的定义如下:
library; // Cannot import because the `pub` keyword is missing fn foo() {} // Can import everything below because they are using the `pub` keyword pub const ONE = __to_str_array("1"); pub struct MyStruct {} impl MyStruct { pub fn my_function() {} } pub enum MyEnum { Variant: (), } pub fn bar() {} pub trait MyTrait { fn my_function(); }可见性(Accessibility)与pub关键字
Sway 的可见性规则非常明确:在库中定义(更一般地说,在 Sway 项目的任何地方)的代码默认被视为private(私有),这意味着其他文件无法访问它们,除非被显式地暴露。
将一个声明暴露给其他文件,需要经过两步:
- 在代码开头添加
pub关键字; - 在
Forc.toml中把该库声明为依赖,然后通过use导入带有pub的声明(详见后文 外部库)。
在上面的示例中,fn foo() {}没有pub,因此无法被其他文件导入;而其余所有带pub的声明均可被导入。
可以被标记为pub的结构包括:
| 结构 | 示例 |
|---|---|
| 全局定义的常量 | pub const ONE = __to_str_array("1"); |
| 结构体 Struct | pub struct MyStruct {} |
| 枚举 Enum | pub enum MyEnum { Variant: (), } |
| 函数 Function | pub fn bar() {} |
| 特质 Trait | pub trait MyTrait { fn my_function(); } |
注意一个细节:在impl MyStruct { pub fn my_function() {} }中,结构体本身被标记为pub,其内部的方法也需要单独使用pub才能被外部调用。pub的可见性修饰是逐项声明的,而不是"结构体公开则方法自动公开"。
库依赖的配置项说明
在引用库的Forc.toml中,通过[dependencies]段声明依赖,这是完成可见性第二步"指定库为依赖"的配置依据。示例见 docs/reference/src/code/language/program-types/libraries/external/my_library/Forc.toml:
[project] authors = ["Fuel Labs <contact@fuel.sh>"] entry = "lib.sw" license = "Apache-2.0" name = "my_library" [dependencies] my_other_library = { path = "../my_other_library" } std = { path = "../../../../../../../../../sway-lib-std" }[project]段中的entry = "lib.sw"指明该项目的库入口文件;[dependencies]中,my_other_library使用path指向本地目录,std指向仓库内的标准库源码目录。除了path外,Sway 的依赖还支持 git 与 IPFS 等来源(对应 forc-pkg/src/source 下的git、ipfs、path等模块),实际项目可根据依赖来源选择声明方式。
库的两种形态:内部库与外部库
根据库文件与使用方在项目中的位置关系,Sway 将库区分为内部库(Internal Library)与外部库(External Library)。下文分别演示二者的使用步骤。
内部库(Internal Library)
当库与使用它的其他程序文件位于同一个src目录时,该库即为内部库。其目录结构如下:
$ tree . ├── Cargo.toml ├── Forc.toml └── src ├── lib.sw └── my_library.sw要在lib.sw中使用同目录下的my_library.sw,只需两步:
- 使用
mod关键字后跟库名,将库引入作用域; - 使用
use关键字从该库中选择性地导入各个条目。
仓库中的完整示例见 docs/reference/src/code/language/program-types/libraries/internal/my_lib/src/lib.sw:
library; mod my_library; use my_library::bar; // `bar` from `my_library` is now available throughout the file执行流程解读:
library;声明当前文件本身也是一个库;mod my_library;把同目录下的my_library.sw作为子模块载入;use my_library::bar;从该模块中按路径选择性导入公开的bar函数。导入后,bar在整个文件中均可直接使用。
同理,外部库中的quix()之所以能被导入,正是因为它在my_other_library中使用了pub关键字(见下节)。
外部库(External Library)
外部库是指位于src目录之外(通常位于另一个完全独立的项目中)的库。其典型目录结构如下:
$ tree . ├── my_library │ ├── Cargo.toml │ ├── Forc.toml │ └── src │ └── lib.sw │ └── my_other_library ├── Cargo.toml ├── Forc.toml └── src └── lib.sw被依赖方my_other_library
my_other_library中定义了一个函数quix(),因为它带有pub关键字,所以可以被my_library导入。其源码见 docs/reference/src/code/language/program-types/libraries/external/my_other_library/src/lib.sw:
library; pub fn quix() {}使用方my_library
要在my_library中使用quix(),同样需要两步:
第一步:添加到依赖(Add to Dependencies)
在my_library的Forc.toml文件的[dependencies]段下,把my_other_library声明为依赖:
[dependencies] my_other_library = { path = "../my_other_library" } std = { path = "../../../../../../../../../sway-lib-std" }第二步:导入(Import)
使用use关键字从my_other_library中按需导入代码。完整示例见 docs/reference/src/code/language/program-types/libraries/external/my_library/src/lib.sw:
library; use my_other_library::quix; // `quix` from `my_other_library` is now available throughout the file内部库与外部库的关键差异
| 对比维度 | 内部库 | 外部库 |
|---|---|---|
| 位置 | 与使用方同处一个src目录 | 在src之外,通常位于独立项目 |
| 引入方式 | mod关键字声明子模块 +use导入 | 在Forc.toml的[dependencies]中声明 +use导入 |
| 适用场景 | 单个项目内部的代码拆分 | 跨项目共享代码(含第三方库) |
| 依赖管理 | 无需修改Forc.toml | 必须在Forc.toml中显式声明 |
库的部署(Deployment)
库本身不能直接部署到区块链上,但可以作为合约(contract)的一部分被部署。这意味着:库中的逻辑最终通过引入它的合约编译并上链,库代码本身不会作为独立的链上实体存在。相关说明见 docs/reference/src/documentation/language/program-types/contract.md。
因此,实践中常见的做法是:
- 将通用的业务逻辑放入库中以实现复用与维护便利;
- 在需要上链的合约中通过
use导入库声明,随合约一起编译部署; - 标准库
std正是通过这种方式被引入到每一个 Sway 项目中的(例如上面的Forc.toml中将std声明为依赖)。
仓库中的配套资料
- 库的基础概念与内部库示例:docs/reference/src/code/language/program-types/libraries/internal/my_lib
- 外部库及跨项目依赖示例:docs/reference/src/code/language/program-types/libraries/external
- 官方标准库(以
library;声明的大型库实例):sway-lib-std/src/lib.sw - Sway 程序类型总览:docs/reference/src/documentation/language/program-types/index.md
- 依赖解析的底层实现:forc-pkg/src/source/mod.rs 及其下的
path.rs、git、reg、ipfs.rs模块
【免费下载链接】sway🌴 Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考