英文:
Comparing the return values of methods with multiple return values
问题
考虑以下示例方法,每个方法都返回三个整数:
func a() (int, int, int) {...}
func b() (int, int, int) {...}
我想知道这些方法的返回值是否相同,类似于这样:
equal := a() == b()
然而,这段代码无法编译,因为编译器期望的是单个值:
my_file.go:14: multiple-value a() in single-value context
my_file.go:14: multiple-value b() in single-value context
我目前的解决方法是创建一个与这些方法具有相同签名的自定义类型,然后创建第三个函数来进行检查:
type multiReturnFunc func() (int, int, int)
func a() (int, int, int) {...}
func b() (int, int, int) {...}
func checkMultiReturns(a, b multiReturnFunc) bool {
a1, a2, a3 := a()
b1, b2, b3 := b()
return a1 == b1 && a2 == b2 && a3 == b3
}
...
equal := checkMultiReturns(a, b)
但我希望有一个更通用的解决方案。
英文:
Considering the following example methods, each of which returns three integers:
func a() (int, int, int) {...}
func b() (int, int, int) {...}
I want to know if the return values of these methods are the same, something like this:
equal := a() == b()
However, this doesn't compile because the compiler is expecting a single value:
my_file.go:14: multiple-value a() in single-value context
my_file.go:14: multiple-value b() in single-value context
My current work around is to create a custom type with the same signature as the methods, and then create a third function to do the checking:
type multiReturnFunc func() (int, int, int)
func a() (int, int, int) {...}
func b() (int, int, int) {...}
func checkMultiReturns(a, b multiReturnFunc) bool {
a1, a2, a3 := a()
b1, b2, b3 := b()
return a1 == b1 && a2 == b2 && a3 == b3
}
...
equal := checkMultiReturns(a, b)
But I would like to have a more general solution.
答案1
得分: 1
这可能不是你想要的准确答案,但是如果你返回结构体而不是三个未命名的整数,你可以直接比较它们。例如:
type XYZ struct{ X, Y, Z int }
func f() XYZ { return XYZ{1, 2, 3} }
func g() XYZ { return XYZ{1, 2, 3} }
func main() {
fmt.Println(f() == g())
// 输出:
// true
}
Playground: http://play.golang.org/p/zFXPqPjTtZ.
英文:
This might not be exactly what you want, but if instead of returning three unnamed ints you return structs, you can compare them directly. E.g.
type XYZ struct{ X, Y, Z int }
func f() XYZ { return XYZ{1, 2, 3} }
func g() XYZ { return XYZ{1, 2, 3} }
func main() {
fmt.Println(f() == g())
// Output:
// true
}
Playground: http://play.golang.org/p/zFXPqPjTtZ.
答案2
得分: 1
使用结构体
你可以通过将结果存储在可比较的结构体值中来稍微改进它:
type Result struct {
a, b, c int
}
p, q := Result{}, Result{}
p.a, p.b, p.c = a()
q.a, q.b, q.c = b()
fmt.Println(p == q)
使用数组
或者你可以使用数组(数组与切片不同,数组是可比较的),虽然这样做不会更短,但你不需要为此定义新类型:
x, y := [3]int{}, [3]int{}
x[0], x[1], x[2] = a()
y[0], y[1], y[2] = b()
fmt.Println(x == y)
通用解决方案(使用reflect
)
可以使用reflect
包构建一个通用解决方案。基本上,它调用两个函数,并比较所有的结果值。省略了错误检查!
func check(v1, v2 reflect.Value) bool {
r1 := v1.Call(nil)
r2 := v2.Call(nil)
if len(r1) != len(r2) {
return false
}
for i, a := range r1 {
if a.Interface() != r2[i].Interface() {
return false
}
}
return true
}
fmt.Println(check(reflect.ValueOf(a), reflect.ValueOf(b)))
在Go Playground上尝试这些代码。
英文:
With structs
You can slightly improve it by storing the result in values of a struct which are comparable:
type Result struct {
a, b, c int
}
And using it:
p, q := Result{}, Result{}
p.a, p.b, p.c = a()
q.a, q.b, q.c = b()
fmt.Println(p == q)
With arrays
Or you can use arrays (arrays are also comparable unlike slices), although this won't be shorter, but you don't need a new type for this:
x, y := [3]int{}, [3]int{}
x[0], x[1], x[2] = a()
y[0], y[1], y[2] = b()
fmt.Println(x == y)
General solution (using reflect
)
A general solution may be constructed using the reflect
package. This basically calls both functions, and compares all the result values. Error checks omitted!
func check(v1, v2 reflect.Value) bool {
r1 := v1.Call(nil)
r2 := v2.Call(nil)
if len(r1) != len(r2) {
return false
}
for i, a := range r1 {
if a.Interface() != r2[i].Interface() {
return false
}
}
return true
}
And using it:
fmt.Println(check(reflect.ValueOf(a), reflect.ValueOf(b)))
Try these on the Go Playground.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论