138

I can not find within the documentation of Vec<T> how to retrieve a slice from a specified range.

Is there something like this in the standard library:

let a = vec![1, 2, 3, 4];
let suba = a.subvector(0, 2); // Contains [1, 2];
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
yageek
  • 4,115
  • 3
  • 30
  • 48

2 Answers2

220

The documentation for Vec covers this in the section titled "slicing".

You can create a slice of a Vec or array by indexing it with a Range (or RangeInclusive, RangeFrom, RangeTo, RangeToInclusive, or RangeFull), for example:

fn main() {
    let a = vec![1, 2, 3, 4, 5];

    // With a start and an end
    println!("{:?}", &a[1..4]);

    // With a start and an end, inclusive
    println!("{:?}", &a[1..=3]);

    // With just a start
    println!("{:?}", &a[2..]);

    // With just an end
    println!("{:?}", &a[..3]);

    // With just an end, inclusive
    println!("{:?}", &a[..=2]);

    // All elements
    println!("{:?}", &a[..]);
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
  • 1
    What's the behavior of the range with no explicit end index? Does it imply the range goes to the end of the vector (e.g. vector length)? I can't find this documented. – Will Brickner Jan 12 '20 at 19:17
  • 1
    Yes, that's right. It's explicitly documented in the docs for the `SliceIndex` impls, for example, [`impl SliceIndex for RangeFrom`](https://doc.rust-lang.org/std/ops/struct.RangeFrom.html#impl-SliceIndex%3Cstr%3E): "Returns a slice of the given string from the byte range `[begin, len)`. Equivalent to `&self[begin .. len]` or `&mut self[begin .. len]`." – Brian Campbell Jan 29 '20 at 04:43
47

If you wish to convert the entire Vec to a slice, you can use deref coercion:

fn main() {
    let a = vec![1, 2, 3, 4, 5];
    let b: &[i32] = &a;

    println!("{:?}", b);
}

This coercion is automatically applied when calling a function:

fn print_it(b: &[i32]) {
    println!("{:?}", b);
}

fn main() {
    let a = vec![1, 2, 3, 4, 5];
    print_it(&a);
}

You can also call Vec::as_slice, but it's a bit less common:

fn main() {
    let a = vec![1, 2, 3, 4, 5];
    let b = a.as_slice();
    println!("{:?}", b);
}

See also:

legends2k
  • 31,634
  • 25
  • 118
  • 222
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 6
    +1 I like `.as_slice()` much better than `[..]` because it conveys the intent. (Converting the Vec into a slice because only slices, not Vecs, implement `io::Read`.) – AndreKR Sep 01 '20 at 10:41