2 ms·
I think you are wrong. I looked and in Rust doc it says that: "Removes the last element from a vector and returns it, or None if it is empty". You better be doi
by FpUser 3y ago
I think you are wrong. I looked and in Rust doc it says that: "Removes the last element from a vector and returns it, or None if it is empty". You better be doing check for "None".
- LegionMammal978 3y agoThe check is still there, that's not under dispute. GP is saying that it's still not the "same thing" as C++, since Rust will refuse to compile the code unless you either perform the check, or actively opt into unchecked access. In contrast, C++ will happily compile the code if you unintentionally neglect to perform the check.
- FpUser 3y agoAre you saying that Rust will refuse to compile code that does not explicitly check option return result for empty?
- __jem 3y agoYes, you cannot use the result without matching on the result/option type.
- Ygg2 3y ago>Are you saying that Rust will refuse to compile code that does not explicitly Depends what you mean by explicit. Look at it like this: pub fn main() { let mut vec : Vec<i32> = vec![]; let x = vec.pop(); println!("{:?}",x); // prints: None } In this case you see the value is missing. vec.pop().expect("I want a value") will panic with "I want a value" because value is empty. And most rigorous way to deal with it is: if let Some(x) = vec.pop() { println!("{:?}",x); } else { println!("EMPTY"); // prints: Empty } will either print value or EMPTY depending on what the vector contains. Types like Result will issue warning that you didn't handle the cases.
- FpUser 3y agofor some reason I can not answer your subsequent reply so I do it here: I looked at your example and played a bit with it and yes I agree with you - compiler does help in this case. My old text: So instead of checking if vector is not empty you check that the return result is not empty. I do not see much difference. If Rust compiler would choke when "else" clause in your example is not present I would understand your point about compiler preventing improper access.
- dtn 3y ago`x`, the value of the Vector access, only exists within the context of the first block. It does not exist in any other scope. This makes it impossible to access when the result is not valid. > If Rust compiler would choke when "else" clause in your example is not present The compiler won't choke, but it will stop you from accessing the value. It doesn't matter if you omit the `else` clause or not, the type system ensures that you can't access invalid values. Here's a bit of an example based off of @Ygg2's code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f9f779c0e4885016773bee8bf4e57363 https://play.rust-lang.org/?version=stable&mode=debug&editio...
- steveklabnik 3y ago> for some reason I can not answer your subsequent reply so I do it here Hacker News will try and discourage really quick back and forth comments. To do so, the reply button is hidden. However, if you click on the timestamp, to go to the comment's own page, you can reply there.
- FpUser 3y agoThanks for the tip. Did not know it
- dureuill 3y agoTo be precise, Rust will refuse to compile code that accesses the value without checking that it is not empty. Rust does that with the combination of "sum types" (aka "enums with data") and pattern matching. An `Option<T>` is either `Some(T)` or `None`. Matching on an option with the pattern `Some(value)` creates a new syntactic scope where the value is accessible. This scope is only entered if the `Option` is actually non-empty. All ways of getting the value from the option are ultimately shorthand for a match in that way. For example, option.unwrap() will either get the value if it there, or panic. Option.unwrap_or(x) will either get the value of it there, or use x instead. In practice this is x100 less error prone than C++. Source: was burned by vector.front() on empty vectors more than once. In C++, UB. In rust, usually the "empty case" is considered when first writing the code, or at least caught during review (unwraps tend to be very visible in reviews)
- Ygg2 3y agoProblem is, you call pop on empty vector in C++, you get nasal demons. Not a case in Rust. I'm not a C++ expert but here is my understanding. Vector is essentially a tuple of (dynamic_array_address: ptr, size: size_t, capacity: size_t). To pop a value from vector you just decrements size. So what happens when you have empty vec? Your size is 0, and you're substracing 1, which causes undefined behavior. Correct way is to check BEFORE you pop_back(). In Rust, any number of invocation of pop() will not result in undefined behavior. You can ignore the value, or you can check it, but it doesn't expose you to UB just for slightly misusing a vector.
- FpUser 3y ago>"Correct way is to check BEFORE you pop_back()" Absolutely and this is exactly what I do. I always check the containers before removing elements. >"In Rust, any number of invocation of pop() will not result in undefined behavior. You can ignore the value, or you can check it, but it doesn't expose you to UB just for slightly misusing a vector." I do not understand "slightly misusing" part. I assume in Rust it would bomb if pop() returns "none" and you try for example add said "none" to some number.
- aldonius 3y agoVec<T>::pop() and similar methods return an Option<T>, so it's a compile-time type error to just add a number to it directly.
- Ygg2 3y ago> I assume in Rust it would bomb if pop() That's the thing. It wouldn't. Worse you can do is make whole program panic, with well defined stack trace and message. It will never return non-sense and pretend all is ok.