3 ms·
Interesting. Just to be clear though: if I'm up to date using rustup with stable, `Vec` and `collect` _are_ using this?
by xscott 5y ago
Interesting. 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.