Search code examples
rusttypesiteratortraits

Passing empty lists to a function that takes an iterator over a trait


I've got some code that needs to accept a list of data structures that could be any of a number of different types, but which all implement Into<SomeType>. So, I say that the parameter is impl IntoIterator<Item = Into<SomeType>> and I'm done. Except...

I can't seem to be able to specify "an empty list" in a concise manner.

Am I screwed, and everyone will just have to use an ugly syntax (Vec::<impl Into<SomeType>>::new()), or is there a simple option I haven't come across before?

Here's example code that demonstrates the problem (also in the playground):

fn takes_iterable_arrays(ia: impl IntoIterator<Item = impl Into<String> + std::fmt::Debug>) {
    println!("{:?}", ia.into_iter().collect::<Vec<_>>());
}

fn main() {
    takes_iterable_arrays(vec!["foo", "bar"]);
    takes_iterable_arrays(Vec::<String>::new());
    takes_iterable_arrays(Vec::<&str>::new());
    //takes_iterable_arrays(vec![]);
    //takes_iterable_arrays(&[]);
    //takes_iterable_arrays([]);
}

The commented-out lines are the variations that I've tried, that I'd like to use, but don't work.


Solution

  • It's impossible to provide “an empty list” without specifying the element type, because takes_iterable_arrays() could decide to change its behavior based on the type (using size_of() or type_name_of()) even if there are no elements.

    So, you're stuck with roughly as much syntax as you're already using. Perhaps the shortest empty IntoIterator you could use is None::<&str>, but that's on the cryptic side. You could add a generic parameter for the element type:

    fn takes_iterable_arrays<T>(ia: impl IntoIterator<Item = T>)
    where
        T: Into<String> + std::fmt::Debug,
    {
        println!("{:?}", ia.into_iter().collect::<Vec<_>>());
    }
    

    This means that takes_iterable_arrays::<&str>([]) is a valid call. It can also help the caller constrain the item type if they're dealing with a generic iterator return type themselves.