Slices of Vec<T> in Rust: How to Get Them Without Losing Your Mind in 2025

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Slices of Vec<T> in Rust: How Do They Work and Why Do You Need Them?

\n\n

If you've ever written in Rust and asked yourself "How do I get a slice of a Vec<T> in Rust?" — you are not alone. This is one of the most popular questions on Stack Overflow, with thousands of views. And for good reason: working with vectors and their slices is a fundamental skill without which no serious Rust project is conceivable.

\n\n

In this article, we won't just show you how to get a slice. We'll break down the best practices of 2025, learn to avoid common pitfalls, and understand why Rust makes us think so much about borrowing. Let's go!

\n\n

What is a slice in Rust?

\n\n

Before taking a slice, let's understand what it is. A slice is a reference to a contiguous sequence of elements in memory. In Rust, a slice is denoted as &[T]. It is not an owning data structure — it simply "looks at" a part of data belonging to someone else (for example, a vector or an array).

\n\n

The main advantage of slices is safety. The Rust compiler guarantees that you won't go out of memory bounds, and the borrowing system won't allow you to modify data while there are active references to it.

\n\n

Why not use the vector directly?

\n\n

A vector (Vec<T>) is an owning structure. If you pass it to a function, you either move it (losing access) or pass a reference. Slices give you flexibility: you can pass only a part of the data without copying it and without losing control over the original vector.

\n\n

For example, you are working with a large data array and want to pass a fragment of it to a function for analysis. A slice is the ideal tool: it is lightweight (just two words: a pointer and a length) and safe.

\n\n

Main ways to get a slice of Vec<T>

\n\n

Let's move on to practice. There are several ways to get a slice from a vector. We'll look at the most popular and convenient ones.

\n\n

1. Indexing operator: &vec[start..end]

\n\n

The most straightforward way is to use the range operator ..:

\n\n
let vec = vec![1, 2, 3, 4, 5];\nlet slice: &[i32] = &vec[1..4]; // slice from index 1 to 4 (excluding 4)\nprintln!("{:?}", slice); // [2, 3, 4]
\n\n

This method uses runtime bounds checking. If you go out of the vector's bounds, the program will panic. This is fine for learning examples, but in production code, you should be more careful.

\n\n

You can use various forms of ranges:

\n\n
    \n
  • &vec[..] — the entire vector
  • \n
  • &vec[2..] — from index 2 to the end
  • \n
  • &vec[..3] — from the beginning to index 3 (excluding)
  • \n
  • &vec[1..=3] — from 1 to 3 inclusive
  • \n
\n\n

2. The .as_slice() method

\n\n

This method returns a slice of the entire vector. It is safer than &vec[..] because it explicitly expresses the intention:

\n\n
let vec = vec![10, 20, 30];\nlet slice: &[i32] = vec.as_slice();\nprintln!("{:?}", slice); // [10, 20, 30]
\n\n

The as_slice() method is especially useful when you want to emphasize that you are working with a slice, not a vector. This makes the code more readable and self-documenting.

\n\n

3. Getting a mutable slice: as_mut_slice()

\n\n

If you need to modify elements inside the slice (but not the vector itself), use as_mut_slice():

\n\n
let mut vec = vec![1, 2, 3];\nlet slice: &mut [i32] = vec.as_mut_slice();\nslice[0] = 100;\nprintln!("{:?}", vec); // [100, 2, 3]
\n\n

Note: the vector must be declared as mut. Also, you cannot have an immutable and a mutable slice at the same time — this would violate the borrowing rules.

\n\n

How to get a sub

Blogs

Book Recommendations