Is there a way to make the following code work (other than accepting an iterator)?
pub fn print_keys<K>(keys: &K,
) where
K: IntoIterator<Item=String> {
for key in keys {
// ^ the trait `Iterator` is not implemented for `&K`
println!("{key}");
}
}
pub fn print_keys<'a, K>(keys: &'a K)
where
&'a K: IntoIterator<Item = &'a String>
{
for key in keys {
println!("{key}");
}
}
This matches how most iterators work; you don't have to restrict to a reference, though (i.e., passing K by-value and adding the exact same bound to K rather than &'a K should work identically and be more lenient).
Passing a reference &K does not make much sense if you want to use the IntoIterator::into_iter() method on K. into_iter takes ownership of your instance of K, creating a type that implements Iterator from it. Passing keys by value instead of by reference would work just fine:
pub fn print_keys<K>(keys: K)
where
K: IntoIterator<Item = String>,
{
for key in keys {
println!("{key}");
}
}
No, there's no "mechanism", nor does it need any particular "making possible". A type variable can stand in for any type. A reference is a type. Thus, a type variable can stand in for a reference type.