Golang 运算符重载

18

我知道Golang不提供运算符重载,因为它认为这会增加复杂性。

所以我想直接为结构体实现运算符重载。

package main

import "fmt"

type A struct {
    value1 int
    value2 int
}

func (a A) AddValue(v A) A {
    a.value1 += v.value1
    a.value2 += v.value2
    return a
}


func main() {
    x, z := A{1, 2}, A{1, 2}
    y := A{3, 4}

    x = x.AddValue(y)

    z.value1 += y.value1
    z.value2 += y.value2

    fmt.Println(x)
    fmt.Println(z)
}

https://play.golang.org/p/1U8omyF8-V

从上述代码中可以看出,AddValue 能够按照我的预期工作。但是,我的唯一担忧是它是通过传值方式实现的,因此我必须每次返回新添加的值。

是否有其他更好的方法,以避免返回累加的变量。

1个回答

33

是的,使用指针接收器:

func (a *A) AddValue(v A) {
    a.value1 += v.value1
    a.value2 += v.value2
}

使用指针接收器,将传递类型为A的值的地址,因此如果您修改指向的对象,则不必返回它,您将修改"原始"对象而不是副本。

您还可以将其命名为Add()。并且出于一致性,您也可以使其参数为指针:

func (a *A) Add(v *A) {
    a.value1 += v.value1
    a.value2 += v.value2
}

因此使用它:

x, y := &A{1, 2}, &A{3, 4}

x.Add(y)

fmt.Println(x)  // Prints &{4 6}

注意事项

请注意,即使现在您有一个指针接收器,如果它们是可寻址的,则仍然可以在非指针值上调用Add()方法,例如以下代码也可以正常运行:

a, b := A{1, 2}, A{3, 4}
a.Add(&b)
fmt.Println(a)

a.Add()(&a).Add() 的简写。在 Go Playground 上试一下。


1
太好了。这个按预期工作。问题:如果我将参数也作为指针传递,那么通过引用而不是值传递它是否有助于性能? - Sundar
4
在处理小型结构体时,这并不重要,你不需要过于关注。但如果你的结构体很大,那么(可能)使用指针会有帮助。关于这个话题的讨论,请参见《参数和返回值中的指针与值》(Pointers vs. values in parameters and return values)。 - icza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接