2作者: iondodon8 个月前原帖
提案:通过 `throw` 标识符在 Go 中隐式错误传播 <p>摘要</p> 本提案引入了一种新的语法约定:在变量声明或赋值中使用标识符 `throw`(例如,`result, throw := errorFunc()`)。当编译器检测到这一用法时,将自动插入对非零错误的检查,并返回所有非错误返回值的零值以及错误。这一机制简化了错误处理,同时不妨碍 Go 语言一贯的明确性和可读性。 <p>动机</p> Go 鼓励显式的错误处理,这常常导致重复的样板代码。例如: <p>result, err := errorFunc() if err != nil { return zeroValue, err }</p> 这种模式虽然清晰,但增加了冗长性,可能会影响可读性,尤其是在包含多个易出错调用的函数中。通过引入一种保留清晰度的语法简写,我们可以减少样板代码,提高开发者的工作效率。 <p>提案</p> 当一个名为 `throw` 的变量被赋值为返回 `error` 的函数的结果,并且外层函数返回一个 `error` 时,编译器将隐式插入: <p>if throw != nil { return zeroValues..., throw }</p> <p>适用场景</p> 短声明: <pre><code> x, throw := doSomething() </code></pre> 标准赋值: <pre><code> x, throw = doSomething() </code></pre> 带赋值的变量声明: <pre><code> var x T; var throw error; x, throw = doSomething() </code></pre> * `throw` 必须是 `error` 类型的变量 * 外层函数必须返回一个 `error` * 该规则仅适用于变量名明确为 `throw` 的情况 <p>示例</p> 传统错误处理: <pre><code>func getUserData(id int) (data Data, err error) { data, err := fetch(id) if err != nil { return Data{}, err } return data, nil }</code></pre> 使用 `throw`: <pre><code>func getUserData(id int) (Data, error) { data, throw := fetch(id) // 自动扩展为:if throw != nil { return Data{}, throw } moreData, throw := fetchMore(id) // 自动扩展为:if throw != nil { return Data{}, throw } return data, nil }</code></pre>