liveBook · Manning

Slicing

As explained in Code Like a Pro in Rust

A Rust slice is a dynamically sized view of a contiguous region of values of one type, represented with a pointer and a length.

A Rust slice is a view of a contiguous sequence of values of one type. An array has a length fixed in its type; a slice can have a length determined at runtime. A slice reference such as `&[u8]` carries a pointer and length, but does not own or resize the underlying storage. section 4.2 section 4.3.1

Borrow and split an array

`let array = [0u8; 64]; let slice: &[u8] = &array; let (left, right) = slice.split_at(32);` The two resulting slices cover nonoverlapping parts of the array. Splitting this way is useful when an algorithm works on separate regions. section 4.2

Prefer a slice reference when a function only needs to inspect a sequence: a `Vec<T>` can supply `&[T]` through `as_slice()` or dereference coercion. For text, `&str` plays the corresponding role and can borrow from a `String`. Use `&mut [T]` when the operation must modify elements; resizing remains the vector’s job. section 4.3.1 section 4.1.2

Listing 4.5 Snippet of the Deref implementation for Vec, from http://mng.bz/6nRe
impl<T, A: Allocator> ops::Deref for Vec<T, A> {
   type Target = [T];

   fn deref(&self) -> &[T] {
       unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
   }
}

impl<T, A: Allocator> ops::DerefMut for Vec<T, A> {
   fn deref_mut(&mut self) -> &mut [T] {
       unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
   }
}

The `Vec` implementations of `Deref` and `DerefMut` show how its pointer and current length become immutable or mutable slice references. section 4.3.1

A slice’s length is captured when it is borrowed, not updated when its source grows. Safe Rust prevents a vector from being resized while a slice borrowing it is still in use: the mutable resize conflicts with that borrow. Treat this as a useful guard against invalidating a view, not a reason to reach for unsafe code. section 4.3.1

For an equal-length copy of `Copy` elements, use `copy_from_slice()` rather than pushing elements one by one. Its implementation uses `ptr::copy_nonoverlapping`; the demonstrated release-mode benchmark copied ten million integers about eight times faster with the slice operation. Measure your own workload before relying on that ratio. section 4.2 section 11.2.3

How Code Like a Pro in Rust covers it

How deep it goes
Works through array splitting, vector coercion, borrow-checker conflicts, and the standard-library implementation of fast slice copying.
Examples
Shows a 64-byte array split at index 32, a rejected vector resize, and a benchmark copying ten million integers.
What it assumes
Assumes familiarity with Rust arrays, vectors, references, and borrowing while demonstrating how those types yield slices.
What you can do after
Apply slices to borrow and split sequences, avoid conflicting vector mutations, and select `copy_from_slice()` for eligible bulk copies.
How it connects
Connects slices to arrays, Vec, Deref, borrowing, string slices, and divide-and-conquer algorithms.

Also explained in

Compare how 16 books explain slicing →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Code Like a Pro in Rust. The section links point to the parts of the book it draws on.