Back to Diem

Vector

language/documentation/book/src/vector.md

latest5.0 KB
Original Source

Vector

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.

Operations

vector supports the following operations via the 0x1::Vector module in the Move standard library:

FunctionDescriptionAborts?
Vector::empty<T>(): vector<T>Create an empty vector that can store values of type TNever
Vector::singleton<T>(t: T): vector<T>Create a vector of size 1 containing tNever
Vector::push_back<T>(v: &mut T, t: T)Add t to the end of vNever
Vector::pop_back<T>(v: &mut T): TRemove and return the last element in vIf v is empty
Vector::borrow<T>(v: &vector<T>, i: u64): &TReturn an immutable reference to the T at index iIf i is not in bounds
Vector::borrow_mut<T>(v: &mut vector<T>, i: u64): &mut TReturn an mutable reference to the T at index iIf i is not in bounds
Vector::destroy_empty<T>(v: vector<T>)Delete vIf v is not empty
Vector::append<T>(v1: &mut vector<T>, v2: vector<T>)Add the elements in v2 to the end of v1If i is not in bounds

More operations may be added overtime

Example

move
use 0x1::Vector;

let v = Vector::empty<u64>();
Vector::push_back(&mut v, 5);
Vector::push_back(&mut v, 6);

assert(*Vector::borrow(&v, 0) == 5, 42);
assert(*Vector::borrow(&v, 1) == 6, 42);
assert(Vector::pop_back(&mut v) == 6, 42);
assert(Vector::pop_back(&mut v) == 5, 42);

Destroying and copying vectors

Some 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:

move
fun destroy_any_vector<T>(vec: vector<T>) {
    Vector::destroy_empty(vec) // deleting this line will cause a compiler error
}

But no error would occur for dropping a vector that contains elements with drop:

move
fun destroy_droppable_vector<T: drop>(vec: vector<T>) {
    // valid!
    // nothing needs to be done explicitly to destroy the vector
}

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:

move
let x = Vector::singleton<u64>(10);
let y = copy x; // compiler error without the copy!

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.

Literals

vector<u8> literals

A 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.

There are currently two supported types of vector<u8> literals, byte strings and hex strings.

Byte 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

Escape SequenceDescription
\nNew line (or Line feed)
\rCarriage return
\tTab
\\Backslash
\0Null
\"Quote
\xHHHex escape, inserts the hex byte sequence HH

Hex Strings

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>

Examples

move
script {
fun byte_and_hex_strings() {
    assert(b"" == x"", 0);
    assert(b"Hello!\n" == x"48656C6C6F210A", 1);
    assert(b"\x48\x65\x6C\x6C\x6F\x21\x0A" == x"48656C6C6F210A", 2);
    assert(
        b"\"Hello\tworld!\"\n \r \\Null=\0" ==
            x"2248656C6C6F09776F726C6421220A200D205C4E756C6C3D00",
        3
    );
}
}

Other vector literals

Currently, there is no support for general vector<T> literals in Move where T is not a u8. However, Move bytecode supports vector<T> constants for any primitive type T. We plan to add vector<T> literals to the source language that can compile to bytecode constants.

Ownership

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 *.