3 ms·
You have to do a very similar operation to has_value() .value() with Rust's optional though... How is opt.ok_or("Value not found.")?; so different from the C++
by carom 2y ago
You have to do a very similar operation to has_value() .value() with Rust's optional though... How is opt.ok_or("Value not found.")?; so different from the C++ type?
- Maxatar 2y agoOne is undefined behavior which may manifest as entirely unpredictable side-effects. The other has semantics that are well specified and predictable. Also while what you wrote is technically valid, it's not really idiomatic to write it the way you did in Rust, you usually write it as: if let Some(value) = some_optional { } At which point value is the "dereferenced" value. Or you can take it by reference if you don't want to consume the value.
- carom 2y agoI prefer ok_or for optionals and map_err for for results in Rust. I believe the way you proposed ends up with very deeply nested code which I try to avoid.
- Kranar 2y agoIt seems like people think dereferencing an unengaged optional results in a crash or exception, but ironically you are actually less likely to get a crash from an optional than you would from dereferencing an invalid pointer. This snippet of code, for example, is not going to cause a crash in most cases, it will simply return a garbage and unpredictable value: auto v = std::optional<int>(); std::cout << *v << std::endl; While both are undefined behavior, you are actually more likely to get a predictable crash from the below code than the above: int* v = nullptr; std::cout << *v << std::endl; I leave it to the reader to reflect on the absurdity of this.
- carom 2y agoI understand what undefined behavior is, I just don't dereference pointers or optionals without first checking them against nullptr or nullopt (respectively). In fact, I generally use the .has_value() and .value() interface on the optional which, to my point in the above comment, is a very similar workflow to using an optional in Rust. I think if you adopted a more defensive programming style where you check your values before dereferencing them, handle all your error cases, you might find C++ is not so scary. I would also recommend not using auto as it makes the types less clear. std::optional<int> v = std::nullopt; if (v == std::nullopt) { return std::unexpected("Optional is empty."); } std::println("{}", *v); If you are dereferencing things without checking that they can be dereferenced I don't know what to tell you.
- d0mine 2y agoWhat is the desired behavior? I see at least 3 options: panic (abort at runtime predictably), compiler error (force handling both Some&Nothing cases [needs language support otherwise annoying], exceptions (annoying to handle properly). There is too much undefined behavior already. Perhaps, 3 types could exist for 3 options.
- calo_star 2y ago`std::optional<T>`'s style is more akin to using if x.is_some() { let x_value = unsafe { x.unwrap_unchecked() }; } everywhere.