The only thing bad about Go's version (other than the usual repetitive code complaints) is it's easy to ignore (ie forget) to handle an error.
And really much of the error handling in Go is by convention (ie, `if err != nil { return nil, err }`) rather than actual language semantics.
Honestly it would be nice to be able to always return the error (without special macros or symbols) if there is one unless I've explicitly setup a handler block.
I've also found (the hard way) that it's possible to mistype a conditional as `err == nil` when it should be `err != nil`. It's a really dumb mistake, but will waste time as you track it down (without the compiler's help).
Nothing keeping you from using the same approach(or even some of the really nice mapping functions), it just lets you get rid of the boilerplate that you see there when you want to.
I don't think it's fair to say that the option Rust gives you is more complex. It's a syntactic convenience which reduces the chance of a someone typing a mistake in the longer form.
Regardless of how simple the language, there is always more than one way to do things. Rust is just giving you the choice to eliminate a lot of boilerplate if you so desire. In reality most Go users will opt to use the style mentioned above instead of something more verbose/complex and most Rust users will likely opt for the new ? operator.
In the Rust one, there's no code to read. How is this somehow less readable than the Go version, where there's dozens of lines of code to read that have nothing to do with the task you're trying to accomplish, that are all completely identical?