Slices
This feature is experimental. You should expect it to change in future versions, cause unexpected behavior, or simply not work at all.
A slice is a dynamically-sized view into a sequence of elements. They can be resized at runtime, but because they don't own the data, they cannot be returned from a circuit. You can treat slices as arrays without a constrained size.
fn main() -> pub u32 {
let mut slice: [Field] = &[0; 2];
let mut new_slice = slice.push_back(6);
new_slice.len()
}
To write a slice literal, use a preceeding ampersand as in: &[0; 2]
or
&[1, 2, 3]
.
It is important to note that slices are not references to arrays. In Noir,
&[..]
is more similar to an immutable, growable vector.
View the corresponding test file here.
Methods
For convenience, the STD provides some ready-to-use, common methods for slices:
push_back
Pushes a new element to the end of the slice, returning a new slice with a length one greater than the original unmodified slice.
fn push_back<T>(_self: [T], _elem: T) -> [T]
example:
fn main() -> pub Field {
let mut slice: [Field] = &[0; 2];
let mut new_slice = slice.push_back(6);
new_slice.len()
}
View the corresponding test file here.
push_front
Returns a new array with the specified element inserted at index 0. The existing elements indexes are incremented by 1.
fn push_front(_self: Self, _elem: T) -> Self
Example:
let mut new_slice: [Field] = &[];
new_slice = new_slice.push_front(20);
assert(new_slice[0] == 20); // returns true
View the corresponding test file here.
pop_front
Returns a tuple of two items, the first element of the array and the rest of the array.
fn pop_front(_self: Self) -> (T, Self)
Example:
let (first_elem, rest_of_slice) = slice.pop_front();
View the corresponding test file here.
pop_back
Returns a tuple of two items, the beginning of the array with the last element omitted and the last element.
fn pop_back(_self: Self) -> (Self, T)
Example:
let (popped_slice, last_elem) = slice.pop_back();
View the corresponding test file here.
append
Loops over a slice and adds it to the end of another.
fn append(mut self, other: Self) -> Self
Example:
let append = &[1, 2].append(&[3, 4, 5]);
insert
Inserts an element at a specified index and shifts all following elements by 1.
fn insert(_self: Self, _index: Field, _elem: T) -> Self
Example:
new_slice = rest_of_slice.insert(2, 100);
assert(new_slice[2] == 100);
View the corresponding test file here.
remove
Remove an element at a specified index, shifting all elements after it to the left, returning the altered slice and the removed element.
fn remove(_self: Self, _index: Field) -> (Self, T)
Example:
let (remove_slice, removed_elem) = slice.remove(3);
len
Returns the length of a slice
fn len(self) -> Field
Example:
fn main() {
let slice = &[42, 42];
assert(slice.len() == 2);
}
as_array
Converts this slice into an array.
Make sure to specify the size of the resulting array. Panics if the resulting array length is different than the slice's length.
fn as_array<N>(self) -> [T; N]
Example:
fn main() {
let slice = &[5, 6];
// Always specify the length of the resulting array!
let array: [Field; 2] = slice.as_array();
assert(array[0] == slice[0]);
assert(array[1] == slice[1]);
}