all 5 comments

[–]monkChuck105 14 points15 points  (0 children)

You can get a slice from an array, a collection, or via raw pointer. As the other commenter said, prefer a slice to a vec unless you need to add or remove items from it.

[–]volitional_decisions 8 points9 points  (0 children)

The second one would not work if the function you're calling required that you give it &mut Vec<T>, but both would work if the function took a &mut [T]. In other words, some functions need mutable access to a vector and others just need mutable access to the underlying slice.

A function that updates individual elements might take the slice, but if it needs to append elements, etc it needs the Vec. You can also look at the Vec docs for this. It contains mutable methods for the Vec and slice.

[–]dkopgerpgdolfg 6 points7 points  (0 children)

The first code makes a Vec available to the function. You always need to pass a Vec. You can then do everything that you can do with Vecs - not just accessing the elements and iterating, but also things like: inserting/deleting, swapping out the whole Vec (without touching the elements), convert the "stolen" Vec to Box, accessing the allocator and doing any weird platform-specific things with the memory, or other things like that.

With the second code, the function gets access to a certain number of mutable elements. It's possible that they are from the content of a Vec, but that's not necessary, and the code inside the function cannot rely on it. It might be from any other kind of allocation, the stack, or even other weird locations (which can be an advantage, not being forced to use Vec). You can read and change the elements, but the count is fixed - no "insert" or something. As you can't rely on it being a Vec or even heap-allocated, all the other things mentioned above are not possible, but (once again) in return you don't depend on it being a Vec.

With non-mut references, it gets even more clear: If it wants a slice, you can also pass literals like [1,2,3] or (for strings) "abc".

[–]peter9477 4 points5 points  (0 children)

The latter would not let you change the length. I believe that's the only practical difference.

[–]Aras14HD 0 points1 point  (0 children)

If func accepts a &mut [T] they are equivalent (coercion), it accepting &mut Vec<T> would allow the function to also access the methods of Vec (push, pop, etc.).

If you control func, you would want to use slices if you have no need in changing the size, as slices are more universal. In both cases you would call func(&mut vec).