Golang 运算符重载

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

Golang Operator Overloading

问题

我理解到,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)
}

从上面的代码中,AddValue 的功能符合我的要求。然而,我唯一关心的是它是按值传递的,因此每次都必须返回新添加的值。

是否有其他更好的方法来避免返回求和后的变量呢?

英文:

I understand that golang does not provide operator overloading, as it believe that it is increasing the complexity.

So I want to implement that for structures directly.

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

From the above code, the AddValue works as I want to. However, my only concern is that it is a pass by value and hence I have to return the newly added value everytime.

Is there any other better method, in order to avoid returning the summed up variable.

答案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)  // 输出 &{4 6}

注意

请注意,即使现在你有一个指针接收器,如果非指针值是可寻址的,仍然可以在其上调用Add()方法,因此以下示例也可以工作:

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

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

英文:

Yes, use pointer receiver:

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

By using a pointer receiver, the address of a value of type A will be passed, and therefore if you modify the pointed object, you don't have to return it, you will modify the "original" object and not a copy.

You could also simply name it Add(). And you could also make its argument a pointer (for consistency):

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

And so using it:

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

x.Add(y)

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

Notes

Note that even though you now have a pointer receiver, you can still call your Add() method on non-pointer values if they are addressable, so for example the following also works:

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

a.Add() is a shorthand for (&a).Add(). Try these on the Go Playground.

huangapple
  • 本文由 发表于 2015年10月9日 22:11:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/33040495.html
匿名

发表评论

匿名网友

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

确定