Check out a free preview of the full The Rust Programming Language course
The "Slices" Lesson is part of the full, The Rust Programming Language course featured in this preview video. Here's what you'd learn in this lesson:
Richard discusses the reference type slice, vector slices, and string slices. A slice will reference a section of pre-exisiting data on the heap without copying or cloning. A brief review of borrowing, mutable references, slices, and string slices is also covered in this segment.
Transcript from the "Slices" Lesson
[00:00:00]
>> So let's move on to slices. So we talked about like, here's a way we can define our nums vec![1, 2, 3]. And how on the stack this is represented as vecMetadata and then the actual 1, 2 and 3 are stored on the heap. So here's our heap.
[00:00:13]
We've got our first_elem_indexes right there. And then this has a. Let's say a capacitor sorry, I guess this should have had four full length is four, but no big deal. So a slice is basically when you say I wanna reuse that heat memory. I just wanna make a new thing on the stack that just basically has different metadata.
[00:00:33]
I just wanna like reference these same pieces of data. Without like copying it without cloning it without having to duplicate anything on the heap. I just wanna represent like maybe a sub section of it, or maybe even the entire thing. So this slice says, ampersand nums, bracket 0 dot dot 2.
[00:00:50]
And basically what this does is it makes something called sliceMetadata. Which looks a lot like vecMetadata except that it's got the first element next that part's the same and the length that part's the same. But it doesn't have a capacity because slices always refer to some other existing allocation.
[00:01:06]
That's where the ampersand comes from is slices are actually reference types. They're basically saying, you know what? I want to look at some sub slice, if you will, [LAUGH] Of an existing vec. So slices are never owned, this is not ever going to be deallocated. It's basically saying, I'm just referencing some data that's already been allocated on the heap, in some other data structure.
[00:01:28]
And when that data structure goes out of scope, it's gonna get deallocated. But I never get deallocated because I'm not responsible for anything. I'm just sort of piggybacking off of somebody else's allocation. And remembering from earlier, we were talking about how these allocations can be kind of expensive from a normal perspective.
[00:01:43]
So slices can be a really nice way to avoid having to do a new allocation having to go back to the bookkeeping system. While still being able to access sub slices of the data, or in some cases even just like making kind of a lightweight. Quasi copy of it without actually having to clone everything.
[00:02:00]
So here we would say, okay, we've got this data on the heap from our nums. And we're saying first_elem_index is usize that's pointing to the same slot that we had for. And the length is 3 in this case, if we're going from 0 to 3. And basically we're just saying, yeah we're just referencing the same exact memory as what was already allocated on the heap previously.
[00:02:23]
So, importantly, slices do not own the elements. They just reference the elements since somebody else is the owner. So, actually, you can't really have a slice that references heap memory. Without somebody else having made that heap memory first, in this case our vector and nums. So, the way that these types look is that nums is a vec of u8.
[00:02:44]
And the slice is ampersand square brackets u8. So slices have their own syntax. They're a language concept. And they're sort of like hard coded into the rust compiler. So this will be the size type of the slice is it's ampersand bracket u8. Whereas nums is vacuous just like before.
[00:03:01]
You can also string slices. So you can basically say I wanna grab some number of chars from within a string. Again, same rules, the string slice doesn't own the elements just references them. You can take a string slice, which is a sort of a sub slice of this string here.
[00:03:14]
We're going from like just a subset of the string here. And whereas previously, we saw that the type of numbers would be a veck of u8. And a slice of numbers would be ampersand square brackets u8. The type of a string slice is just ampersand str. That's it.
[00:03:31]
All the same rules apply a slice doesn't own the elements just references them. Except in this case it's referencing elements of characters within a string. Rather than u8 as a Vec or whatever the heck might be holding. If you want to get all of the contents of the Veck as a slice, you can just say nums.as_slice.
[00:03:47]
Or if you wanna get a slice of all the characters in the string, you can say string.as_str. Okay, let's let's review and then we'll do the exercises. So let's review we started off by talking about borrowing. So we said let years_ref is ampersand Vec of i32, which is assigned to ampersand years.
[00:04:09]
So this is an immutable borrow so this right here is the borrow part. And in this right here is the reference type. So the way to get a reference type is to perform a borrow. We talked about how borrowing is basically not transferring ownership. Instead, it's sort of lending access to something.
[00:04:23]
It's saying, hey, you can take a look at this reference to my years. But you're not gonna deallocate anything because I'm still owning it. I'm still in charge of cleaning it up we talked about mutable references. Which are basically like references except they allow you to mutate the contents of the thing unlike immutable references.
[00:04:40]
And we talked about why thanks to rusts concurrency guarantees to try to rule out databases as a guarantee. Basically says, you're allowed to have exactly one mutable reference active at one time within the current scope. Or any number of immutable references. But if you have even one mutable reference, you can't have any immutable ones active at the same time.
[00:04:59]
And you can't have any other mutable ones ones active at the same time. Then we talked about slices, and how you can have a slice of a years back like this. And say I wanna get just a sub slice of that and how that's gonna give me back.
[00:05:12]
A slice that has the same type of element as the vec that we were talking about. And it's gonna in fact use the same memory as that. But it's just gonna be a reference to that memory. This is not actually gonna be something owned, that's going to be deallocated, no deallocations will happen.
[00:05:26]
The deallocations are all up to the original thing that we're sort of making a slice of. And then finally, we talked about string slices, how we have string slices which can be exactly the same thing. But just for strings instead of Vex.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops