Go:单值上下文中的多个值 [英] Go: multiple value in single-value context
问题描述
假设我有以下功能: p>
类型项目结构{
/ pre>
值int
名称字符串
}
func Get(value int)(Item,error){
// some code
return item,nil
}
如何将一个新变量分配给
item.Value
。在介绍错误处理之前,我的函数刚刚返回item
,我可以这样做:code> val:= Get(1).Value
现在我这样做: p>
item,_:= Get(1)
val:= item.Value
有没有办法直接访问第一个返回的变量?
许多谢谢
解决方案如果是多值返回函数,则不能引用特定值的字段或方法调用函数时的结果。
如果其中一个是
错误
,那么它就是一个原因(这是功能可能失败),您应该不绕过它,因为如果你这样做,你的后续代码可能也可以失败(例如造成运行时的恐慌)。
然而,可能有些情况下,您知道代码不会在任何循环中失败umstances。在这些情况下,您可以提供一个帮助函数(或方法),它将丢弃
错误
(或者如果仍然出现则会引发运行时的紧急情况)。
如果您从代码中提供函数的输入值,并且您知道它们正常工作,则可能会出现这种情况。
这个很好的例子是模板
和regexp
包:如果您在编译时提供了一个有效的模板或regexp,那么您可以确保在运行时始终可以无误地解析。因此,模板
包提供了必须(t *模板,错误错误)*模板
功能和regexp
包提供MustCompile(str string)* Regexp
功能:它们不返回
示例:
//text是一个有效的模板,解析它不会失败
var t = template.Must(template.New(name)。 (text))
//`^ [az] + \ [[0-9] + \] $`是一个有效的正则表达式,总是编译
var validID = regexp.MustCompile(`^ [az] + \ [[0-9] + \] $`)
回到你的案例
如果你可以肯定
Get()
不会为某些输入值产生错误
,您可以创建一个帮助者Must()
函数,它不会返回错误
,但是如果仍然出现则会引发运行时的紧急情况:func Must(i Item,err error)Item {
if err!= nil {
panic(err)
}
return i
}
但是,不要在任何情况下使用,只要确定成功。用法:
val:=必须(获取(1))价值
/ pre>
替代/简化
您甚至可以进一步简化将
Get()
调用到您的帮助函数中,让我们称之为MustGet
:func MustGet(value int)Item {
i,err:= Get(value)
if err!= nil {
恐慌(错误)
}
返回i
}
:
val:= MustGet(1).Value
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.
Let's say I have the following function:
type Item struct { Value int Name string } func Get(value int) (Item, error) { // some code return item, nil }
How can I assign a new variable to
item.Value
elegantly. Before introducing the error handling, my function just returneditem
and I could simply do this:val := Get(1).Value
Now I do this:
item, _ := Get(1) val := item.Value
Isn't there a way to access directly the first returned variable?
Many thanks
解决方案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.
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).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 thetemplate
andregexp
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 thetemplate
package provides theMust(t *Template, err error) *Template
function and theregexp
package provides theMustCompile(str string) *Regexp
function: they don't returnerror
s because their intended use is where the input is guaranteed to be valid.Examples:
// "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]+\]$`)
Back to your case
IF you can be certain
Get()
will not produceerror
for certain input values, you can create a helperMust()
function which would not return theerror
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
Alternative / Simplification
You can even simplify it further if you incorporate the
Get()
call into your helper function, let's call itMustGet
:func MustGet(value int) Item { i, err := Get(value) if err != nil { panic(err) } return i }
Usage:
val := MustGet(1).Value
这篇关于Go:单值上下文中的多个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!