vector<T>
is the only primitive collection type provided by Move. A vector<T>
is a homogenous collection of T
's that can grow or shrink by pushing/popping values off the "end".
A vector<T>
can be instantiated with any type T
. For example, vector<u64>
, vector<address>
, vector<0x42::MyModule::MyResource>
, and vector<vector<u8>>
are all valid vector types.
vector
LiteralsVectors of any type can be created with vector
literals.
Syntax | Type | Description |
---|---|---|
In these cases, the type of the vector
is inferred, either from the element type or from the vector's usage. If the type cannot be inferred, or simply for added clarity, the type can be specified explicitly:
vector<u8>
literalsA common use-case for vectors in Move is to represent "byte arrays", which are represented with vector<u8>
. These values are often used for cryptographic purposes, such as a public key or a hash result. These values are so common that specific syntax is provided to make the values more readable, as opposed to having to use vector[]
where each individual u8
value is specified in numeric form.
There are currently two supported types of vector<u8>
literals, byte strings and hex strings.
Byte strings are quoted string literals prefixed by a b
, e.g. b"Hello!\n"
.
These are ASCII encoded strings that allow for escape sequences. Currently, the supported escape sequences are:
Hex strings are quoted string literals prefixed by a x
, e.g. x"48656C6C6F210A"
.
Each byte pair, ranging from 00
to FF
, is interpreted as hex encoded u8
value. So each byte pair corresponds to a single entry in the resulting vector<u8>
.
vector
provides several operations via the std::vector
module in the Move standard library, as shown below. More operations may be added over time. Up-to-date document on vector
can be found here.
vector
sSome behaviors of vector<T>
depend on the abilities of the element type, T
. For example, vectors containing elements that do not have drop
cannot be implicitly discarded like v
in the example above--they must be explicitly destroyed with vector::destroy_empty
.
Note that vector::destroy_empty
will abort at runtime unless vec
contains zero elements:
But no error would occur for dropping a vector that contains elements with drop
:
Similarly, vectors cannot be copied unless the element type has copy
. In other words, a vector<T>
has copy
if and only if T
has copy
. However, even copyable vectors are never implicitly copied:
Copies of large vectors can be expensive, so the compiler requires explicit copy
's to make it easier to see where they are happening.
For more details see the sections on type abilities and generics.
As mentioned above, vector
values can be copied only if the elements can be copied. In that case, the copy must be explicit via a copy
or a dereference *
.
Escape Sequence | Description |
---|---|
Function | Description | Aborts? |
---|---|---|
vector[]
vector[]: vector<T>
where T
is any single, non-reference type
An empty vector
vector[e1, ..., en]
vector[e1, ..., en]: vector<T>
where e_i: T
s.t. 0 < i <= n
and n > 0
A vector with n
elements (of length n
)
New line (or Line feed)
Carriage return
Tab
\\
Backslash
\0
Null
\"
Quote
\xHH
Hex escape, inserts the hex byte sequence HH
vector::empty<T>(): vector<T>
Create an empty vector that can store values of type T
Never
vector::is_empty<T>(): bool
Return true
if the vector v
has no elements and false
otherwise.
Never
vector::singleton<T>(t: T): vector<T>
Create a vector of size 1 containing t
Never
vector::length<T>(v: &vector<T>): u64
Return the length of the vector v
Never
vector::push_back<T>(v: &mut vector<T>, t: T)
Add t
to the end of v
Never
vector::pop_back<T>(v: &mut vector<T>): T
Remove and return the last element in v
If v
is empty
vector::borrow<T>(v: &vector<T>, i: u64): &T
Return an immutable reference to the T
at index i
If i
is not in bounds
vector::borrow_mut<T>(v: &mut vector<T>, i: u64): &mut T
Return a mutable reference to the T
at index i
If i
is not in bounds
vector::destroy_empty<T>(v: vector<T>)
Delete v
If v
is not empty
vector::append<T>(v1: &mut vector<T>, v2: vector<T>)
Add the elements in v2
to the end of v1
Never
vector::reverse_append<T>(lhs: &mut vector<T>, other: vector<T>)
Pushes all of the elements of the other
vector into the lhs
vector, in the reverse order as they occurred in other
Never
vector::contains<T>(v: &vector<T>, e: &T): bool
Return true if e
is in the vector v
. Otherwise, returns false
Never
vector::swap<T>(v: &mut vector<T>, i: u64, j: u64)
Swaps the elements at the i
th and j
th indices in the vector v
If i
or j
is out of bounds
vector::reverse<T>(v: &mut vector<T>)
Reverses the order of the elements in the vector v
in place
Never
vector::reverse_slice<T>(v: &mut vector<T>, l: u64, r: u64)
Reverses the order of the elements [l, r) in the vector v
in place
Never
vector::index_of<T>(v: &vector<T>, e: &T): (bool, u64)
Return (true, i)
if e
is in the vector v
at index i
. Otherwise, returns (false, 0)
Never
vector::insert<T>(v: &mut vector<T>, i: u64, e: T)
Insert a new element e
at position 0 <= i <= length, using O(length - i) time
If i
is out of bounds
vector::remove<T>(v: &mut vector<T>, i: u64): T
Remove the i
th element of the vector v
, shifting all subsequent elements. This is O(n) and preserves ordering of elements in the vector
If i
is out of bounds
vector::swap_remove<T>(v: &mut vector<T>, i: u64): T
Swap the i
th element of the vector v
with the last element and then pop the element, This is O(1), but does not preserve ordering of elements in the vector
If i
is out of bounds
vector::trim<T>(v: &mut vector<T>, new_len: u64): u64
Trim the vector v
to the smaller size new_len
and return the evicted elements in order
new_len
is larger than the length of v
vector::trim_reverse<T>(v: &mut vector<T>, new_len: u64): u64
Trim the vector v
to the smaller size new_len
and return the evicted elements in the reverse order
new_len
is larger than the length of v
vector::rotate<T>(v: &mut vector<T>, rot: u64): u64
rotate(&mut [1, 2, 3, 4, 5], 2) -> [3, 4, 5, 1, 2] in place, returns the split point ie. 3 in this example
Never
vector::rotate_slice<T>(v: &mut vector<T>, left: u64, rot: u64, right: u64): u64
rotate a slice [left, right) with left <= rot <= right in place, returns the split point
Never