What do you think about Iterator::single?


#21

Well, do you think that it’s worth an RFC?


#22

I think this is such a small and self-contained API addition that you’re better off just submitting PR against Rust repo and there the libs team will start an RFC inline if needed. Go for it!


#23

(Posting here because of @mbrubeck’s referral on IRC)

I have a similar need for this, and I’d like the same API as what @Centril wrote here – one that returns None instead of returning an error or panicking.

My use case is searching through a bunch of strings in a Trie; sometimes it’s quite useful to ensure that there’s only one match.


#24

C# has two forms of this, but both of them throw for n>1

If the rust one doesn’t just panic, it feels like it’d need to be

enum IteratorSingleError<T> {
    MoreThanOneItem(T),
    EmptyIterator,
}

because the emptiness check will read the second item.

That said, I feel like if you’d do anything but .unwrap() such a thing, you’d be better off writing the code a different way, so I’m inclined to say that it would be best to just always panic for n>1, the same way that C# throws in those cases. (Notably, there’s no TrySingle in C#, their pattern for non-throwing equivalents.)

So I think I like the fn single(self) -> Option<Self::Item> version – the same signature as Iterator::last, which matches up with C#'s Enumerable.Last/Enumerable.LastOrDefault.


#25

Something like this would also be useful:

let value = iter.single().or_ok(Error::InvalidInput)?;

So returning None (or Err) from single() would be more convenient than panicking. But yes, using MoreThanOneItem(T) to recover from this error is not realistic.


#26

Proposed in https://github.com/rust-lang/rust/pull/55355.