用途与别名
use
语法可用于为其他模块中的成员创建别名.use
可以创建两种范围的别名:在整个模块范围内有效,或在特定表达式块范围内有效.
use
有几种不同的语法形式.从最简单的开始,我们有以下用于为其他模块创建别名的语法:
use <address>::<module name>;use <address>::<module name> as <module alias name>;
例如:
script { use std::vector; use std::vector as V;}
use std::vector;
为 std::vector
创建了别名 vector
.这意味着在可以使用模块名 std::vector
的地方(假设这个 use
在当前作用域内),都可以改用 vector
.use std::vector;
等效于 use std::vector as vector;
类似地,use std::vector as V;
允许使用 V
代替 std::vector
module 0x42::example { use std::vector; use std::vector as V;
fun new_vecs(): (vector<u8>, vector<u8>, vector<u8>) { let v1 = std::vector::empty(); let v2 = vector::empty(); let v3 = V::empty(); (v1, v2, v3) }}
如果要导入特定的模块成员(如函数,结构体或常量),可以使用以下语法:
use <address>::<module name>::<module member>;use <address>::<module name>::<module member> as <member alias>;
例如:
script { use std::vector::empty; use std::vector::empty as empty_vec;}
这使得你可以不使用完整限定名来调用函数 std::vector::empty
,而可以分别使用 empty
和 empty_vec
.同样,use std::vector::empty;
等效于 use std::vector::empty as empty;
module 0x42::example { use std::vector::empty; use std::vector::empty as empty_vec;
fun new_vecs(): (vector<u8>, vector<u8>, vector<u8>) { let v1 = std::vector::empty(); let v2 = empty(); let v3 = empty_vec(); (v1, v2, v3) }}
如果需要同时为多个模块成员添加别名,可以使用以下语法:
use <address>::<module name>::{<module member>, <module member> as <member alias> ... };
例如:
module 0x42::example { use std::vector::{push_back, length as len, pop_back};
fun swap_last_two<T>(v: &mut vector<T>) { assert!(len(v) >= 2, 42); let last = pop_back(v); let second_to_last = pop_back(v); push_back(v, last); push_back(v, second_to_last) }}
如果需要在添加模块成员别名的同时为模块本身添加别名,可以在单个 use
语句中使用 Self
.Self
是一种特殊成员,指代模块本身.
script { use std::vector::{Self, empty};}
为明确起见,以下所有写法都是等价的:
script { use std::vector; use std::vector as vector; use std::vector::Self; use std::vector::Self as vector; use std::vector::{Self}; use std::vector::{Self as vector};}
如果需要,您可以为任何项设置任意数量的别名
module 0x42::example { use std::vector::{ Self, Self as V, length, length as len, };
fun pop_twice<T>(v: &mut vector<T>): (T, T) { // 上述 `use` 语句提供的所有选项都可用 assert!(vector::length(v) > 1, 42); assert!(V::length(v) > 1, 42); assert!(length(v) > 1, 42); assert!(len(v) > 1, 42);
(vector::pop_back(v), vector::pop_back(v)) }}
在 module
内部
Section titled “在 module 内部”在 module
内部,所有 use
声明都可以使用,无论声明顺序如何.
module 0x42::example { use std::vector;
fun example(): vector<u8> { let v = empty(); vector::push_back(&mut v, 0); vector::push_back(&mut v, 10); v }
use std::vector::empty;}
模块内通过 use
声明的别名在该模块内都可用.
此外,引入的别名不能与其他模块成员冲突.详见 唯一性 部分
在表达式内部
Section titled “在表达式内部”您可以在任何表达式块的开头添加 use
声明
module 0x42::example {
fun example(): vector<u8> { use std::vector::{empty, push_back};
let v = empty(); push_back(&mut v, 0); push_back(&mut v, 10); v }}
与 let
类似,表达式块中通过 use
引入的别名在该块结束时会被移除.
module 0x42::example {
fun example(): vector<u8> { let result = { use std::vector::{empty, push_back}; let v = empty(); push_back(&mut v, 0); push_back(&mut v, 10); v }; result }}
尝试在块结束后使用别名会导致错误
module 0x42::example { fun example(): vector<u8> { let result = { use std::vector::{empty, push_back}; let v = empty(); push_back(&mut v, 0); push_back(&mut v, 10); v }; let v2 = empty(); // 错误!// ^^^^^ 未绑定的函数 'empty' result }}
任何 use
必须是块中的第一个项.如果 use
出现在任何表达式或 let
之后,会导致解析错误
script { fun example() { { let x = 0; use std::vector; // 错误! let v = vector::empty(); } }}
别名必须遵循与其他模块成员相同的规则.这意味着结构体或常量的别名必须以 A
到 Z
开头
address 0x42 { module data { struct S {} const FLAG: bool = false; fun foo() {} } module example { use 0x42::data::{ S as s, // 错误! FLAG as fLAG, // 错误! foo as FOO, // 有效 foo as bar, // 有效 }; }}
在给定作用域内,所有通过 use
声明引入的别名必须是唯一的.
对于模块来说,这意味着通过 use
引入的别名不能重复
module 0x42::example { use std::vector::{empty as foo, length as foo}; // 错误! // ^^^ 重复的 'foo'
use std::vector::empty as bar; use std::vector::length as bar; // 错误! // ^^^ 重复的 'bar'}
并且,它们不能与模块中的其他成员产生命名冲突
address 0x42 { module data { struct S {} } module example { use 0x42::data::S;
struct S { value: u64 } // 错误! // ^ 与上方的别名'S'冲突 }}
在表达式块内部,它们彼此之间不能重叠,但可以遮蔽外部作用域中的别名或名称
表达式块内部的 use
别名可以遮蔽外部作用域中的名称(模块成员或别名).
与局部变量的遮蔽规则类似,这种遮蔽会在表达式块结束时失效;
module 0x42::example {
struct WrappedVector { vec: vector<u64> }
fun empty(): WrappedVector { WrappedVector { vec: std::vector::empty() } }
fun example1(): (WrappedVector, WrappedVector) { let vec = { use std::vector::{empty, push_back}; // 现在'empty'指向std::vector::empty
let v = empty(); push_back(&mut v, 0); push_back(&mut v, 1); push_back(&mut v, 10); v }; // 现在'empty'重新指向Self::empty
(empty(), WrappedVector { vec }) }
fun example2(): (WrappedVector, WrappedVector) { use std::vector::{empty, push_back}; let w: WrappedVector = { use 0x42::example::empty; empty() }; push_back(&mut w.vec, 0); push_back(&mut w.vec, 1); push_back(&mut w.vec, 10);
let vec = empty(); push_back(&mut vec, 0); push_back(&mut vec, 1); push_back(&mut vec, 10);
(w, WrappedVector { vec }) }}
未使用的Use或别名
Section titled “未使用的Use或别名”未使用的 use
会导致错误
module 0x42::example { use std::vector::{empty, push_back}; // 错误! // ^^^^^^^^^ 未使用的别名'push_back'
fun example(): vector<u8> { empty() }}