Uses and Aliases
The use
syntax can be used to create aliases to members in other modules. use
can be used to
create aliases that last either for the entire module, or for a given expression block scope.
Syntax
There are several different syntax cases for use
. Starting with the most simple, we have the
following for creating aliases to other modules
use <address>::<module name>;
use <address>::<module name> as <module alias name>;
For example
use Std::Vector;
use Std::Vector as V;
use Std::Vector;
introduces an alias Vector
for Std::Vector
. This means that anywhere you
would want to use the module name Std::Vector
(assuming this use
is in scope), you could use
Vector
instead. use Std::Vector;
is equivalent to use Std::Vector as Vector;
Similarly use Std::Vector as V;
would let you use V
instead of Std::Vector
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)
}
If you want to import a specific module member (such as a function, struct, or constant). You can use the following syntax.
use <address>::<module name>::<module member>;
use <address>::<module name>::<module member> as <member alias>;
For example
use Std::Vector::empty;
use Std::Vector::empty as empty_vec;
This would let you use the function Std::Vector::empty
without full qualification. Instead you
could use empty
and empty_vec
respectively. Again, use Std::Vector::empty;
is equivalent to
use Std::Vector::empty as empty;
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)
}
If you want to add aliases for multiple module members at once, you can do so with the following syntax
use <address>::<module name>::{<module member>, <module member> as <member alias> ... };
For 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)
}
If you need to add an alias to the Module itself in addition to module members, you can do that in a
single use
using Self
. Self
is a member of sorts that refers to the module.
use Std::Vector::{Self, empty};
For clarity, all of the following are equivalent:
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};
If needed, you can have as many aliases for any item as you like
use Std::Vector::{
Self,
Self as V,
length,
length as len,
};
fun pop_twice<T>(v: &mut vector<T>): (T, T) {
// all options available given the `use` above
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))
}
Inside a module
Inside of a module
all use
declarations are usable regardless of the order of declaration.
address 0x42 {
module 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;
}
}
The aliases declared by use
in the module usable within that module.
Additionally, the aliases introduced cannot conflict with other module members. See Uniqueness for more details
Inside an expression
You can add use
declarations to the beginning of any expression block
address 0x42 {
module 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
}
}
}
As with let
, the aliases introduced by use
in an expression block are removed at the end of that
block.
address 0x42 {
module 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
}
}
}
Attempting to use the alias after the block ends will result in an error
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(); // ERROR!
// ^^^^^ unbound function 'empty'
result
}
Any use
must be the first item in the block. If the use
comes after any expression or let
, it
will result in a parsing error
{
let x = 0;
use Std::Vector; // ERROR!
let v = Vector::empty();
}
Naming rules
Aliases must follow the same rules as other module members. This means that aliases to structs or
constants must start with A
to Z
address 0x42 {
module Data {
struct S {}
const FLAG: bool = false;
fun foo() {}
}
module Example {
use 0x42::Data::{
S as s, // ERROR!
FLAG as fLAG, // ERROR!
foo as FOO, // valid
foo as bar, // valid
};
}
}
Uniqueness
Inside a given scope, all aliases introduced by use
declarations must be unique.
For a module, this means aliases introduced by use
cannot overla
address 0x42 {
module Example {
use Std::Vector::{empty as foo, length as foo}; // ERROR!
// ^^^ duplicate 'foo'
use Std::Vector::empty as bar;
use Std::Vector::length as bar; // ERROR!
// ^^^ duplicate 'bar'
}
}
And, they cannot overlap with any of the module's other members
address 0x42 {
module Data {
struct S {}
}
module Example {
use 0x42::Data::S;
struct S { value: u64 } // ERROR!
// ^ conflicts with alias 'S' above
}
}
Inside of an expression block, they cannot overlap with each other, but they can shadow other aliases or names from an outer scope
Shadowing
use
aliases inside of an expression block can shadow names (module members or aliases) from the
outer scope. As with shadowing of locals, the shadowing ends at the end of the expression block;
address 0x42 {
module 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' now refers to Std::Vector::empty
let v = empty();
push_back(&mut v, 0);
push_back(&mut v, 1);
push_back(&mut v, 10);
v
};
// 'empty' now refers to 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 })
}
}
}
Unused Use or Alias
An unused use
will result in an error
address 0x42 {
module Example {
use Std::Vector::{empty, push_back}; // ERROR!
// ^^^^^^^^^ unused alias 'push_back'
fun example(): vector<u8> {
empty()
}
}
}