Golang接收器(Receiver)与普通函数参数的区别

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

Golang Receiver vs Normal function parameter

问题

我对于何时将值作为接收器传递,何时在函数中使用值作为参数感到困惑。我的main.go文件如下所示:

package main

import "fmt"

type tenNumbers []int

func main() {
	arrayOfTen := newArrayOneToTen()
	arrayOfTen.print()
}

// 不是接收器函数,因为你没有接收任何东西
func newArrayOneToTen() tenNumbers {
	myNumbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	return myNumbers
}

// 是接收器函数,因为你接收了数组
func (t tenNumbers) print() {
	for _, value := range t {
		if value%2 == 0 {
			fmt.Println(value, "even")
		} else {
			fmt.Println(value, "odd")
		}
	}
}

如果我将函数更改为将int切片作为参数传递,它仍然可以正常工作,如下所示:

package main

import "fmt"

type tenNumbers []int

func main() {
	arrayOfTen := newArrayOneToTen()
	print(arrayOfTen)
}

// 不是接收器函数,因为你没有接收任何东西
func newArrayOneToTen() tenNumbers {
	myNumbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	return myNumbers
}

// 是接收器函数,因为你接收了数组
func print(t tenNumbers) {
	for _, value := range t {
		if value%2 == 0 {
			fmt.Println(value, "even")
		} else {
			fmt.Println(value, "odd")
		}
	}
}

这两种方式有什么区别吗?我对何时使用接收器或参数感到困惑。

英文:

I am confused at when should I pass in my value as a receiver and when should I use the value as a parameter in my function. My main.go file is as shown below:

package main

import "fmt"

type tenNumbers []int

func main() {

	arrayOfTen := newArrayOneToTen()

	arrayOfTen.print()

}

// not a receiver function because you are not receive anything
func newArrayOneToTen() tenNumbers {
	myNumbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

	return myNumbers
}

// receiver function because you receive the array
func (t tenNumbers) print() {
	for _, value := range t {
		if value%2 == 0 {
			fmt.Println(value, "even")
		} else {
			fmt.Println(value, "odd")
		}
	}
}

If I change my functions to passing in the slice of int as parameters, it still works as shown below. :

package main

import "fmt"

type tenNumbers []int

func main() {

	arrayOfTen := newArrayOneToTen()

	print(arrayOfTen)

}

// not a receiver function because you are not receive anything
func newArrayOneToTen() tenNumbers {
	myNumbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

	return myNumbers
}

// receiver function because you receive the array
func print(t tenNumbers) {
	for _, value := range t {
		if value%2 == 0 {
			fmt.Println(value, "even")
		} else {
			fmt.Println(value, "odd")
		}
	}
}

Is there a difference between the 2? I am confused as to when I should use receiver or parameter?

答案1

得分: 2

区别在于,在第一种情况下,类型tenNumbers将在其方法集中具有print()方法,而在第二种情况下则没有。

如果只是想运行函数,这并不重要:你可以使用两种解决方案。

如果必须实现一个接口,或者函数属于该类型,那么使用方法可以使代码更有组织性。参见:https://stackoverflow.com/questions/66224523/functions-as-the-struct-fields-or-as-struct-methods/66224586#66224586

另外,请注意函数无法通过名称在运行时访问,而方法可以。参见:https://stackoverflow.com/questions/37384473/call-functions-with-special-prefix-suffix/37384665#37384665

另一个考虑因素可能与泛型有关,方法不能引入新的类型参数,只能“使用”在类型定义中列出的类型参数。函数可以引入新的类型参数。参见:https://stackoverflow.com/questions/70668236/how-to-create-generic-method-in-go-method-must-have-no-type-parameters/70668559#70668559

英文:

The difference is that in the first case the type tenNumbers will have a print() method in its method set, in the second case it won't.

This doesn't matter if you just want to run the function: you may use both solutions.

Use methods if you must implement an interface, and also if the function belongs to the type, this keeps code more organized. See: https://stackoverflow.com/questions/66224523/functions-as-the-struct-fields-or-as-struct-methods/66224586#66224586

Also note that functions cannot be accessed at runtime by name, methods can be. See: https://stackoverflow.com/questions/37384473/call-functions-with-special-prefix-suffix/37384665#37384665

Another consideration may be regarding generics is that methods can't introduce new type parameters, only "use" type parameters listed at the type definition. Functions can introduce new type parameters. See: https://stackoverflow.com/questions/70668236/how-to-create-generic-method-in-go-method-must-have-no-type-parameters/70668559#70668559

huangapple
  • 本文由 发表于 2022年9月2日 15:58:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/73579461.html
匿名

发表评论

匿名网友

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

确定