Slice parameter

If I have a function defined like

pub fn test_func<B>(bytes: &B)
                where
                    B: AsRef<[u16]>,
                    B: IntoIterator<Item = u16>,
                {
              
                }

I can call it like

let u16_values: Vec<u16> = vec![2332, 3234];
test_func(&u16_values);

let array: [u16; 2] = [4092, 56551];
test_func(&array);

But how can I call it with a slice like

let array: [u16; 4] = [4092, 56551, 60234, 4234];
let slice = &array[0..2];
test_func(slice);

Is it possible to make it universal ?

It's enough to keep the AsRef<[u16]> bound. You can then just call bytes.as_ref().iter().

(The B: IntoIterator bound was useless anyway, because B: IntoIterator doesn't imply &B: IntoIterator, so you couldn't have used it in the function body.)

If you want to support dynamically-sized types such as slices, you need to remove the implicit Sized bound by adding U: ?Sized to the function signature. Playground.

2 Likes

EDIT: corrected by @H2CO3 below, AsRef doesn't have an blanket implementation for all types, but does have implementations for selective collection of common types, including the slice type [T].

the trait AsRef is not reflexive, so you can't use AsRef<[u16]> as bounds here if you want to take a slice as argument. there's multiple alternatives, each has slightly different semantic implications, for example, Borrow<[u16]>, Deref<Target = [u16]> etc.

That is incorrect. [T] is AsRef<[T]>.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.