Transcript from the "Vectors" Lesson
>> So, we're gonna talk about a few things here. First is the vec type that we're gonna talk about usize, which someone asked about earlier. Talk about stack memory, and finally, heap memory. So we're gonna get a little bit further into our exploration of memory and how it relates to rust.
[00:00:14] Okay, let's start with talking about vectors. So, we saw previously how to define an array of years. Here's how to define a vector or vec for short of years. So I'm saying let mut yours is Vec<i32. So there's those angle brackets like we saw with options, so this is a type parameter saying, = vec exclamation point, so this is a macro, 1985, 2000, 2005.
[00:00:39] Now, unlike arrays, we actually can increase the size of vectors. So I can say years.push 2010. So now years has 4 elements ending in 2010. So this is pushing 2010 onto the end of the vector. We can also call push again on it and push that onto the end.
[00:00:55] So now we'd have 2010 and 2015 on the end there. Notice by the way that we would only be able to do this if we have let mut yours. If I tried to call push, and this was not defined let mut it would say you can't do that because push mutates.
[00:01:07] And you're only allowed to mutate things that are defined with mut. And then once I was done with that, I could say number of years and then call the len method on yours which returns the length of the years vector. So, couple things to note about this. Number one, much like arrays, you do have to specify what the type of every single one of these elements is.
[00:01:29] So in this case, I said, every single one of these elements inside this vec has to be i32. But, unlike arrays, I don't have to hard code the length. So that's because the length is allowed to change at runtime with a vector, I'm allowed to push things onto the vec.
[00:01:42] And I'm also allowed there's other things like pop, which will take things off of the vec. And that's also why there's a length method. So you can imagine with an array, it wouldn't be that useful to have a method for it because the length is hard coded at compile time, it's never gonna change.
[00:01:55] But in the case of a vector, it actually can change at runtime. So the len method will return the current length of that year's vector. So initially, if I call .len on this, it would be 3, but at this point it would now be 5 because I pushed two more elements onto it.
[00:02:12] Usize comes up in the context of length because len actually returns not a u64 or u16 or u32 but rather something called usize. So usize is a little bit interesting, it's a little bit different than the number size that we've seen before. And what's different about it is that it's almost always in practice either a u32 or use 64 because usize the size of it varies based on the system you're compiling for.
[00:02:43] So on a 64 bit system, usize is equivalent to a u64, but on a 32 bit system, it's equivalent to a u32. And if there are still 16 bits systems around on a 16 bit system, it would be the equivalent of u16. I don't know of any 128 bit systems, but if there were usize on those systems would be u128.
[00:03:04] So, a good example of a modern 32 bit system is Web Assembly is actually 32 bit right now. Whereas pretty much every other machine you're gonna encounter is gonna be 64 bit. Like [LAUGH] this laptop is 64 bit, any like mobile phone you've got or like a tablet is gonna be 64 bit, 32 bit systems are like older systems or Web Assembly.
[00:03:25] Although granted, they're actually working on a 64 bit version of Web Assembly, but it hasn't really been released yet. I don't think there are any browsers that implement it yet. So in practice, really what usize means, at least in this day and age is generally speaking is gonna be either u64 or u32 depending on what you're compiling for, it's almost always gonna be one of those two.
[00:03:46] And that's the type of length like whenever you store the length of a particular vector, it's always gonna be usize. This is actually a really common thing where length values are stored as usize. It's true for vectors, it's also true for strings, it's true for a number of different data structures.
[00:04:03] So this is the most common context in which you will see usize come up. But other one that we didn't talk about was array indexes. When your indexing into an array with the square brackets, the type of the value that you put in there is also gonna be usize.
[00:04:18] So, not really something that you need to like get a ton of detail about but it's basically is just either u32 or u64. Okay, so let's talk about a few more differences between vectors and arrays. So here we have an array called nums and this is 3 u8s, so 1, 2, 3.
[00:04:37] And here we have a vector of u8s. So you can kind of see the differences in the types here. We still have the u8 because we're say, all the elements have to be u8 but we didn't have to put the 3 here, although we did put vec and then angle brackets instead of square brackets.
[00:04:49] And of course, when you're making the vector you actually call the vec macro, rather than just using square brackets. This does highlight another feature of macros that we haven't seen before, which is macros can actually be used to you can call macros without parentheses. You can use call them with other things like square brackets or curly braces.
[00:05:10] That's just like one of the things that macros let you do that functions don't. Functions are always called with parentheses but macros, yeah, you can potentially call them with other things depending on the macro. The vec macro says give me square brackets because it wants to kind of look like arrays whereas like print line and format, that wouldn't really make sense.
[00:05:25] So of course, they want you to use parentheses. Now of node, we can't actually do a for loop over either of these. Whether it's a vec, or it's an array, we can still do a for loop over that thing. Basically, this might seem like, well, what's the difference?
[00:05:48] Why would you you ever want to use an array if you could use a vec? And basically there's a trade off there in terms of how they're represented in memory. And basically the trade off there sort of set the stage for the number one biggest factor in language performance, which is how heap memory is managed.
[00:06:06] So, it might seem like a small difference and it might seem like you would always use a vec cuz it's just like way better. It's more flexible, there's no reason to ever use an array. But behind the scenes in terms of memory management, they're quite different. And, this is also relates to some of the borrow checking errors that you'll see later on.
[00:06:21] So, we're gonna take some time now and just talk about the difference between stack memory and heap memory and how that pertains to vec in particular.
>> So vectors are still you have to be consistently typed within a vector, correct?
>> Correct, yeah, you still have the same restriction where every single one of the elements and that really has to do with the for loops.
[00:06:37] Like when you're iterating through this Russ needs to be able to say like, I know exactly what the type of num is. And then in both of these cases, that's true. In both cases, it knows that it's always gonna have a u8 in there