Doesn't the producer know best whether the producer failed?
By day I work with a team in a language that sees errors ride on the exception handling system. Staying within the original example, I see code like this all the time (too often, even, but that's another topic for another day):
try {
file = getFile()
} catch(/* ... */) {
fileUnavailable()
}
Here, the assumption of getFile that the caller wanted an error was incorrect. A Result-using language would end up in a similar place.Idiomatic Go says leave it to the caller. Like above, when only wants to know if there is "file or no file" without concern for why there is no file, then:
file, _ := getFile() // The second return argument is an error.
if file == nil {
fileUnavailable()
}
I doubt either way makes much difference in this contrived example, but the difference shows up when it extends out into real code. There are plusses and minuses to each way of seeing the world. Tradeoffs, as always. let _ = fs::mkdir_all() // Error ignored, Rust will not complain because you explicitly assigned to _
Or if the function returns something I need but I don't care about the error: let Ok(file) = get_file() else {
file_unavailable();
return
}
upload_file(file);
Or this: let file = get_file().unwrap_or_default()>
file, _ := getFile() // The second return argument is an error.
if file == nil {
fileUnavailable()
}
That very often doesn't work in Go. Most functions which return errors offer no guarantee whatsoever about the return value if there is an error. No one would consider it a breaking change to modify the return in case of error. And many functions return a struct, where Go offers no way to compare two arbitrary struct values for equality, or to check if an arbitrary struct value is that struct's "zero value".So no, Go does not recommend (or even endorse) this pattern.