Priority when using named return parameters and explicit return values

Hello,

In the Effective Go article, i saw the following code

// Compile returns a parsed representation of the regular expression.
func Compile(str string) (regexp *Regexp, err error) {
    regexp = new(Regexp)
    // doParse will panic if there is a parse error.
    defer func() {
        if e := recover(); e != nil {
            regexp = nil    // Clear return value.
            err = e.(Error) // Will re-panic if not a parse error.
        }
    }()
    return regexp.doParse(str), nil
}

I understand that deferred functions can access named return parameters, it makes sense.
In the deferred function, err is set to e if e is of type Error.
When using named return parameters, we can use simple return without specifying values to return. The last line of the function, though, uses an “explicit” return to specify return values. What is the behavior when this return statement is executed ?
My hypothesis on this is that because we only set err when recover() does not return nil, then the explicit return is never actually executed, because it means regexp.doParse(str) panic’d.
Am I right ?

Thank you !

A return statement with values does exactly the same thing as in a function where the result values are not named. It is only the empty return statement that is different in a function with named result variables.

Thank you for your answer. I still don’t understand the behavior of this code, and why it works. In this snippet, there is no empty return statement, why can we avoid it ?

The

return regexp.doParse(str), nil

Is equivalent to

regexp = regexp.doParse(str)
err = nil
return

If a panic happens in doParse, the deferred code will kick in and overwrite the regexp and err variables.

2 Likes

Thank you for the clarification !

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.