3 ms·
Feels like archaeology or a treasure hunt to track that down, but yeah it all looks very clever: https://doc.rust-lang.org/src/core/iter/traits/iterator.rs.htm
by xscott 5y ago
Feels like archaeology or a treasure hunt to track that down, but yeah it all looks very clever:
https://doc.rust-lang.org/src/core/iter/traits/iterator.rs.html#1774-1776 https://doc.rust-lang.org/src/core/iter/traits/iterator.rs.h... (collect)
https://doc.rust-lang.org/src/alloc/vec/mod.rs.html#2549-2554 https://doc.rust-lang.org/src/alloc/vec/mod.rs.html#2549-255... (FromIterator for Vec)
https://doc.rust-lang.org/src/alloc/vec/spec_from_iter.rs.html#37 https://doc.rust-lang.org/src/alloc/vec/spec_from_iter.rs.ht... (SpecFromIter for Vec)
https://doc.rust-lang.org/src/alloc/vec/spec_extend.rs.html#22 https://doc.rust-lang.org/src/alloc/vec/spec_extend.rs.html#... (SpecExtend for Vec)
https://doc.rust-lang.org/src/core/iter/range.rs.html#854 https://doc.rust-lang.org/src/core/iter/range.rs.html#854 (TrustedLen for Range)
https://doc.rust-lang.org/src/core/iter/range.rs.html#17 https://doc.rust-lang.org/src/core/iter/range.rs.html#17 (TrustedStep for isize)
The `TrustedLen for Range` is marked unstable, and the issue tracker has comments from just 8 days ago. Does that mean this only works with nightly?
Back to the topic though,the iterator/collect solution looks uglier than the for loop to my eyes, and I still can't think of any (reasonable) case where unsigned array/slice/vec indexes are better. :-)
- LegionMammal978 5y agoThe compiler and standard library are allowed to use whatever unstable features they want. So really, things like TrustedLen can be seen as implementation details that nightly programs can tap into, provided they're not worried about building on all future versions of the compiler.
- xscott 5y agoInteresting. Just to be clear though: if I'm up to date using rustup with stable, `Vec` and `collect` _are_ using this?
- tialaramex 5y agoThey've been using this for a long time. I actually have a checkout of Rust's git from summer 2021 when I was contemplating doing a bunch of doc changes (to use arrays instead of Vec in examples where that was now reasonable and maybe clearer) sitting around and used that to quickly verify what you summarised above when I answered. So this was all true in like 1.53 or whatever that checkout is, and presumably long before. There are quite a few of these unstable Traits laying about in Rust's standard library that express important ideas that we can't live without, and yet are not something that's nailed down solidly enough to stabilize, the standard library is allowed to do this while claiming to be stable even though we are not - the rationale is that if they rip out one of these unstable traits, they can do the work to fix all the mess and deliver stability in the stable API anyway, whereas the same could not be true for some third party crate. Another unstable but useful feature, check out Pattern: https://doc.rust-lang.org/std/str/pattern/trait.Pattern.html https://doc.rust-lang.org/std/str/pattern/trait.Pattern.html Rust's string matching code uses Pattern everywhere so that even though Rust does not have ad hoc polymorphism (method overloading in C++): "clowns".contains("owns") // That's a literal string yet also "clowns".contains('c') // That's not a string it's just one character and "clowns".contains(char::is_lowercase) // A method on characters which here functions as a simple predicate A sound API and yet also more convenient and more extensible.
- xscott 5y agoCool stuff. I've also seen generic traits and tuples used to fake function overloading with different arity: trait Foo<T> { fn foo(&self, other: T); } impl Foo<()> for &str { fn foo(&self, _other: ()) { print!("0 params\n"); } } impl Foo<(f64,)> for &str { fn foo(&self, _other: (f64,)) { print!("1 params\n"); } } impl Foo<(f64, f64)> for &str { fn foo(&self, _other: (f64, f64)) { print!("2 params\n"); } } fn main() { "".foo(()); // pretend that's 0 args "".foo((1.0,)); // pretend that's 1 args "".foo((1.0, 2.0)); // pretend that's 2 args } Not quite as pretty, but it works, and you can be generic or specific over each sub-item in the tuple.