如何在结构体值赋值期间省略函数调用的次要返回值

huangapple go评论76阅读模式
英文:

How to omit a secondary return from a function call during a struct value assignment

问题

我想在类型为struct的变量声明中分配一个值,但是我需要调用一个返回第二个值(错误)的函数,我希望在赋值时忽略该错误。

有没有办法这样做?例如:

type myStruct struct{
	address common.Address
}


func main() {
	newVar := myStruct{
	  address: common.HexToAddress("xyz") 
	}
}

问题在于common.HexToAddress()返回2个值,一个是common.Address,另一个是错误。我希望忽略错误并像上面那样进行赋值。我希望不必这样做:

var newVar2 myStruct
myStruct,_ = common.HexToAddress("xyz") 
英文:

I would like to assign a value within a variable declaration of type struct, however, I need to call a function that returns a secondary value (an error) which I would like to disregard in the assignment.

Is there a way to do so? For example:

type myStruct struct{
	address common.Address
}


func main() {
	newVar := myStruct{
	  address: common.HexToAddress("xyz") 
	}
}

The issue is that common.HexToAddress() returns 2 values, a common.Address as well as an error. I would like to omit the error and assign it as above. I would prefer not to have to do:

var newVar2 myStruct
myStruct,_ = common.HexToAddress("xyz") 

答案1

得分: 5

通常不建议忽略错误,这可能是语言不容易实现此功能的原因之一。

话虽如此,有时你会看到一种模式,即某个包提供了一个Must函数,用于那些只需在错误上调用panic()的情况,例如在初始化包级变量时。

例如,有一个名为text/template.Must的函数。实现简单地检查错误,如果不是nil就会触发panic。你也可以考虑添加这样一个函数(可能是局部函数),以便你可以将结构体初始化写成:

newVar := myStruct{
  address: must(common.HexToAddress("xyz")),
}
// ...
func must(address common.Address, err error) common.Address { ... }

这依赖于一个特性,即如果一个函数返回多个值,并且另一个函数接受相同数量的参数,你可以直接在前一个函数的返回值上调用后一个函数

如果你不想走得那么远,你确实需要显式地忽略第二个返回值,将其赋值给空白标识符_。当然,你可以单独执行这个操作,这样你仍然可以使用结构体字面量,但可能不比你最初提出的方法更简洁:

address, _ := common.HexToAddress("xyz")
newVar := myStruct{address: address}
英文:

It's usually not exactly recommended to ignore errors, which may be one reason why the language does not make this easy.

That being said, a pattern you see sometimes is a package offering a Must function, for those cases where just doing a panic() on an error is the right thing to do; e.g., when initializing package-level variables.

For example, there's text/template.Must. The implementation simply tests the error and panics if it is not nil. You can consider adding such a function as well (possibly local to your file), allowing you to write your struct initialization as:

newVar := myStruct{
  address: must(common.HexToAddress("xyz")),
}
// ...
func must(address common.Address, err error) common.Address { ... }

This relies on the feature that if a function returns multiple values, and another function takes the same amount of parameters, you can invoke the latter directly on the return values of the former.

If you don't want to go that far, you do need to explicitly ignore the second return value by assigning it to the blank identifier _. You could of course do that separately, so that you still get to use a structure literal, but it may not be any cleaner than what you suggested originally:

address, _ := common.HexToAddress("xyz")
newVar := myStruct{address: address}

答案2

得分: 0

你可能正在寻找某种语法糖。Go语言故意在这方面保持简洁,因为在语言设计者看来,这样做往往会使事情变得不够明显,从而降低可读性。所以在这里你的选择有限。

如果你真的不关心错误,以下是你的选择:

像你建议的那样,将其赋值给一个临时变量(通常是最自然/可读性最好的选项):

addr, _ := common.HexToAddress("xyz")
newVar := myStruct{
    address: addr,
}

使用匿名函数的返回值:

newVar := myStruct{
    address: func() common.Address { addr, _ := common.HexToAddress("xyz"); return addr }(),
}

如果你控制common包,考虑添加一个忽略(或在出错时引发panic)的变体:

newVar := myStruct{
    address: common.MustHexToAddress("xyz"),
}

编写自己的包装函数:

func hexToAddress(hex string) common.Address {
    addr, _ := common.HexToAddress(hex)
    return addr
}

newVar := myStruct{
    address: hexToAddress("xyz"),
}
英文:

You're probably looking for some kind of syntactic sugar. Go is intentionally sparse on such things, because in the opinion of the language designers, it tends to make things less obvoius, thus less readable. So you have limited options here.

If you really don't care about the error, here are your options:

Assign to a temporary variable as you suggested (usually the most natural/readable option):

addr, _ := common.HexToAddress("xyz")
newVar := myStruct{
    address: addr,
}

Use the return value of an anonymous function:

newVar := myStruct{
    address: func() common.Address { addr, _ := common.HexToAddress("xyz"); return addr }(),
}

If you control the common package, consider adding a variant that ignores (or panics on) errors:

newVar := myStruct{
    address: common.MustHexToAddress("xyz"),
}

Write your own wrapper function:

func hexToAddress(hex string) common.Address {
    addr, _ := common.HexToAddress(hex)
    return addr
}

newVar := myStruct{
    address: hexToAddress("xyz"),
}

huangapple
  • 本文由 发表于 2021年8月8日 04:20:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/68695842.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定