3 ms·
let mut v = vec![1,2,3,4]; for i in v.iter() { v.push(i);}; And that doesn't work, because the v.iter() is sugar for Vec::iter(&v), while the v.push(i) is suga
by namibj 5y ago
let mut v = vec![1,2,3,4];
for i in v.iter() { v.push(i);};
And that doesn't work, because the v.iter() is sugar for Vec::iter(&v), while the v.push(i) is sugar for Vec::push(&mut v, i) . I think it'd use deref coercion on the i, as Vec::iter(&v) gives you `i: &isize`. If this wasn't ints (or other `Copy` types, for that matter), you'd need to use .into_iter() to consume the Vec and get ownership of the entries while iterating, or use `.push(i.clone())` because `Vec<T>::push(&mut self, T)` is the signature, and you can only go automatically from `&T` to `T` for `Copy` types. Actually, it _may_ even need `v.push(*i)`, thinking about it. Try on https://play.rust-lang.org https://play.rust-lang.org
- benreesman 5y agoSo I don't have the same intuition for desugaring `vec!` that I do for desugaring `for (auto&& blah : blarg)`, but in either case if you desugar it the problem becomes a lot more clear. The Rust borrow checker errors I'm sure become second nature just like the C++ template instantiation ones do, but that is faint praise. To get some inscrutable C++ template instantiation error you have to mess with templates, and that's for people who know what they're doing. In Rust it seems like the borrow checker isn't for pros, it's C++-template complexity that you need to get basic shit done. C++ is actually a pretty gradually-typed language, and I'm in general a fan of gradual typing. I don't mind that some people prefer BDSM-style typing, but IMHO that goes with GC e.g. Haskell a lot better than it does with trying to print something out or copy it or whatever.
- zxzax 5y agoIt's not the same as C++ template errors. This is something that will directly cause a segfault in your code, that the Rust compiler is able to catch; AFAIK no C++ compiler would be able to catch that.
- kd5bjo 5y agoThe problem here is that you’re trying to iterate over `v` and modify it at the same time. The usual fix is to first decide the changes that should be made, and then apply them after the loop: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f466f888f95c2cf3ccbeffbc10f76b7d https://play.rust-lang.org/?version=stable&mode=debug&editio... Alternatively, you can loop over indices instead of values, which doesn’t require the loop to maintain a reference to `v` across iterations: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a9d565552c4a8b37b123c42101e91239 https://play.rust-lang.org/?version=stable&mode=debug&editio...