将方法的返回值与多个返回值进行比较

时间:2015-10-19 08:57:24

标签: go

考虑以下示例方法,每个方法返回三个整数:

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)

但我希望有一个更通用的解决方案。

2 个答案:

答案 0 :(得分: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上尝试这些。

答案 1 :(得分:0)

这可能不是您想要的,但如果不返回三个未命名的整数而返回结构,您可以直接比较它们。 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
}

游乐场:http://play.golang.org/p/zFXPqPjTtZ