If you pass &[u32]
(as well as if you pass &Vec<u32>
) no value is moved. In case of &[u32]
, you pass a reference to (all or some) contents of the Vec
, including an element count, but excluding information about the excess capacity (allocated memory) of the overall vector.
If you would pass &Vec<u32>
to the function, you'd unnecessarily include the information about the excess capacity when referencing the Vec
. This is usually avoided because working with &[u32]
is more flexible. For example, you can pass a sub-slice of the original Vec
.
A value of type &Vec<u32>
can be automatically coerced into a &[u32]
when you call the function and the function expects a &[u32]
.
When you want to transfer ownership of the Vec
, you pass Vec<T>
. When you just want to access the elements (or when it's okay to copy or clone them element-by-element where needed), you pass a &[T]
instead. But you almost never pass &Vec<T>
. The same holds for strings: You either pass String
or &str
, depending on your use case, but almost never &String
.
Technically &[u32]
is implemented by passing a wide pointer, which includes the base address of the actual data (skipping the information on the excess capacity) as well as the element count.
Of course it's entirely up to you how to format the error message. The convention is meant to provide some consistency. Actually I cited the recommendation for the Display
implementation of Error
types. But I assume the same applies to panic messages. Ideally, your user would never see such panic messages. Those errors which happen more frequently could be handled specially and use a custom mechanism to be presented to the user in a nice way, I guess.