单值上下文中的多个值 [英] Multiple values in single-value context
问题描述
由于 Go 中的错误处理,我经常以多值函数结束.到目前为止,我的管理方式非常混乱,我正在寻找最佳实践来编写更简洁的代码.
Due to error handling in Go, I often end up with multiple values functions. So far, the way I have managed this has been very messy and I am looking for best practices to write cleaner code.
假设我有以下功能:
type Item struct {
Value int
Name string
}
func Get(value int) (Item, error) {
// some code
return item, nil
}
如何优雅地为 item.Value
分配一个新变量.在引入错误处理之前,我的函数只返回了 item
,我可以简单地这样做:
How can I assign a new variable to item.Value
elegantly. Before introducing the error handling, my function just returned item
and I could simply do this:
val := Get(1).Value
现在我这样做:
item, _ := Get(1)
val := item.Value
有没有办法直接访问第一个返回的变量?
Isn't there a way to access directly the first returned variable?
推荐答案
在多值返回函数的情况下,调用函数时不能引用结果的特定值的字段或方法.
In case of a multi-value return function you can't refer to fields or methods of a specific value of the result when calling the function.
如果其中一个是 error
,则有 原因(这是函数 可能 失败),您应该 不要绕过它,因为如果你这样做,你的后续代码可能也会失败(例如导致运行时恐慌).
And if one of them is an error
, it's there for a reason (which is the function might fail) and you should not bypass it because if you do, your subsequent code might also fail miserably (e.g. resulting in runtime panic).
然而,在某些情况下,您知道代码在任何情况下都不会失败.在这些情况下,您可以提供一个 helper 函数(或方法),该函数(或方法)将丢弃 error
(如果仍然发生,则引发运行时恐慌).
如果您通过代码为函数提供输入值,并且您知道它们有效,则可能就是这种情况.
很好的例子是 template
和 regexp
包:如果您在编译时提供有效的模板或正则表达式,您可以确定它们始终可以在运行时无错误地解析.为此,template
包提供了 Must(t *Template, err error) *Template
函数和 regexp
包提供了 MustCompile(str string) *Regexp
函数:它们不返回 error
,因为它们的预期用途是保证输入有效.
However there might be situations where you know the code will not fail in any circumstances. In these cases you can provide a helper function (or method) which will discard the error
(or raise a runtime panic if it still occurs).
This can be the case if you provide the input values for a function from code, and you know they work.
Great examples of this are the template
and regexp
packages: if you provide a valid template or regexp at compile time, you can be sure they can always be parsed without errors at runtime. For this reason the template
package provides the Must(t *Template, err error) *Template
function and the regexp
package provides the MustCompile(str string) *Regexp
function: they don't return error
s because their intended use is where the input is guaranteed to be valid.
示例:
// "text" is a valid template, parsing it will not fail
var t = template.Must(template.New("name").Parse("text"))
// `^[a-z]+[[0-9]+]$` is a valid regexp, always compiles
var validID = regexp.MustCompile(`^[a-z]+[[0-9]+]$`)
回到你的案例
IF 你可以确定 Get()
不会为某些输入值产生 error
,你可以创建一个 helper Must()
函数不会返回 error
但如果它仍然发生会引发运行时恐慌:
Back to your case
IF you can be certain Get()
will not produce error
for certain input values, you can create a helper Must()
function which would not return the error
but raise a runtime panic if it still occurs:
func Must(i Item, err error) Item {
if err != nil {
panic(err)
}
return i
}
但是你不应该在所有情况下都使用它,当你确定它成功时.用法:
But you should not use this in all cases, just when you're sure it succeeds. Usage:
val := Must(Get(1)).Value
替代/简化
如果您将 Get()
调用合并到您的辅助函数中,您甚至可以进一步简化它,我们称之为 MustGet
:
You can even simplify it further if you incorporate the Get()
call into your helper function, let's call it MustGet
:
func MustGet(value int) Item {
i, err := Get(value)
if err != nil {
panic(err)
}
return i
}
用法:
val := MustGet(1).Value
看到一些有趣/相关的问题:
这篇关于单值上下文中的多个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!