返回首页
最新
提案:通过 `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>