Given they are eager, it stands to reason that they should only be used with constants and precomputed values for the parameter res. Is this correct or am I missing missing something?
Given that, how useful are these methods in practice over their lazy counterparts: and_then and or_else?
I'd be keen to see some real world examples of how these methods are used. Are there any specific use cases where these eager methods shine through over the lazy variants? I'm struggling to think of cases where this would be true.
Note: I've cross posted about this on the Rust Discord as well. I'm hoping for some good examples of where this would be useful.
Here's one quick example for capturing errors and converting them to the application's error type.
There are a lot of potential uses for .or() and the other similar methods of Result. For an error type where the messages they contained are static strings, .or() would be appropriate. If an error variant contains a string dynamically created, .or_else() would be better.
In pratice, personally, I find myself using the lazy counterparts of such methods more often. But there are some cases where the eager methods are better, where computation overhead is minimal or the values are static.
There are so many features, methods, types, etc. in Rust it's difficult, if not impossible, to always have an idea how they could be applied. Just make a mental note that they're there, and as you write more Rust code, eventually you'll run into cases where it suddenly makes sense to apply them.
as unnecessary closures add nothing but line noise and optimizer overhead. There's no reason to use a lazy variant when the value on the right is trivial.
s.split_whitespace()
.map(|s| s.parse())
.collect::<Result<Vec<i32>, _>>()
// One example usage.
.or(Err(ConversionError("Bad number string passed to convert().")))
I am right in saying that Err and Conversion instances are created when the parsing fails and when it succeeds?
I presume, in this instance, you don't care too much about the instance creation cost (which is low) as it's more readable?
In this specific example, there's no runtime creation cost. What's happening here is an enum variant ConversionError and its static &str are resolved at compile time. So when this code runs, if the .collect() succeeds, it's Result object is returned directly, and if it fails the precompiled error is returned.
In this case, the log() methods are going to run no matter what. The compiler assumes you want the return value (probably ()) passed as the parameter after invoking them. In this case, .and_then(|| log("")) is better.
I don't think I've ever personally used .and(), and I have written a lot of Rust code. I chalk this up to each of us having different styles and habits. There are a lot of things I don't find useful, but I'm sure others have good reasons for having such features available. If there's a use for .and(), I guess I'll know it when I need it.
Yeah. "Symmetry" is the rationale behind some of the feature requests / bug reports I've seen. "We have list.sort(), but we don't have list.unsort(), we should add that"
TBH, and and and_then immediately became much less useful once ? existed. If you're in code handling results, it's most common that you're in a function returning a result too, and thus instead of a.and_then(|| b) it's more common that you'd just write a?; b instead.
or(_else) is certainly more useful, especially on Option, but I think I mostly use unwrap_or(_else) because if I'm doing it I often didn't want an Option out.