如何在Go语言中使用接收器?

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

How to use receivers in Go?

问题

有两个代码示例如下。

示例1:

package main

import "fmt"

type Dat struct {
	Num int
}

func (d *Dat) Fn1a(i int) {
	d.Num = i
}

func (d *Dat) Fn2a() {
	d.Num++
}

func main() {
	var d Dat
	d.Fn1a(1)
	d.Fn2a()
	fmt.Println(d)
}

示例2:

package main

import "fmt"

type Dat struct {
	Num int
}

func Fn1b(i int) *Dat {
	d := &Dat{i}
	return d
}

func (d *Dat) Fn2b() *Dat {
	d.Num++
	return d
}

func main() {
	d := Fn1b(1).Fn2b()
	fmt.Println(d)
}

这两个示例输出相同的结果。

我的问题是关于这些示例之间的区别。我注意到以下区别。

尽管在示例1中,type Dat struct可以更改为type dat struct,但在示例2中,当将type Dat struct更改为type dat struct时,golint会显示一个警告:exported func Fn1b returns unexported type *main.dat, which can be annoying to use。因此,在示例1中,dat可以直接用作一个非公开的struct

还有其他区别吗?例如,哪个更好?

非常感谢您的时间和建议。对于我的幼稚问题,我感到非常抱歉。

英文:

There are two code samples as follows.

Sample 1:

package main

import "fmt"

type Dat struct {
	Num int
}

func (d *Dat) Fn1a(i int) {
	d.Num = i
}

func (d *Dat) Fn2a() {
	d.Num++
}

func main() {
	var d Dat
	d.Fn1a(1)
	d.Fn2a()
	fmt.Println(d)
}

Sample 2:

package main

import "fmt"

type Dat struct {
	Num int
}

func Fn1b(i int) *Dat {
	d := &Dat{i}
	return d
}

func (d *Dat) Fn2b() *Dat {
	d.Num++
	return d
}

func main() {
	d := Fn1b(1).Fn2b()
	fmt.Println(d)
}

Both samples output the same results.

My question is about the difference between these samples. I could notice the following difference.

Although in Sample 1, type Dat struct can be changed to type dat struct, in Sample 2, when type Dat struct is changed to type dat struct, golint shows a warning: exported func Fn1b returns unexported type *main.dat, which can be annoying to use. So in Sample 1, dat can be used directly as a struct without being public.

Are there any other differences? For example, which is better?

Thank you so much for your time and advices. And I'm sorry for my immature question.

答案1

得分: 1

你的问题中有一些不同的主题:

1)导出和未导出的类型

如果你有一个被导出的函数,该函数返回一个未导出的类型,在你的包外调用该函数将会导致错误。

所以,假设不允许将类型Dat设为未导出。

2)哪种解决方案更好?

这取决于具体情况,但总体而言,示例2更好。你可以看到,主函数更加简洁。如果你的结构体更加复杂,你可以在其中做一些处理。例如,如果你的结构体有一个参数是映射类型,你需要使用make()函数初始化该映射。在示例1中,你需要在每次创建新的Dat类型时都这样做。

通常,你会将该函数命名为NewDat()。如果你在创建新的Dat变量时总是使用该函数,这样做也会使你的代码更加灵活,便于进行更改。

英文:

There are some different topics inside your question:

1) Exported and unexported types

If you have a function, which is exported and that function returns an unexported type this will cause to an error, when you call that function outside of your package.

So let's say that it is not allowed to make your type Dat unexported.

2) Which solution is better?

That depends on, but at all it would be sample 2. You see how much cleaner your main function is. If your struct will be more complicated you can do some stuff there. For example your struct has a parameter which is a map you need to initialize that map by using make(). In sample 1 you need to do this every time you create a new Dat type.

Normally you would call that function NewDat(). If you always use that function when creating a new Dat variable that makes your code also more flexible for changes.

huangapple
  • 本文由 发表于 2017年4月2日 11:03:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/43164183.html
匿名

发表评论

匿名网友

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

确定