在定义 struct 的 method 时, 好像这这两种方式没有区别:
func (st StructType) MyMethod1() {}
func (st *StructType) MyMethod2() {}
而且调用访问时好像, 也没区别:
st := StructType{}
st.MyMethod1()
st.MyMethod2()
于是我就困惑了, 我看了 github 上主流的几个项目, 好像都倾向于使用MyMethod2这种接收者为指针类型的定义方式, 很少见到MyMethod1的方式, 这里有什么规范吗?
1
rrfeng 2017-11-09 14:56:12 +08:00
|
2
boboliu 2017-11-09 15:02:53 +08:00 via Android
为什么不试试 st := &StructType{} 呢?
|
3
cloudzhou 2017-11-09 15:03:55 +08:00 1
传参,指针和结构体的区别,即使传递指针,对指针来说,也是创建一个变量把指针复制过去。
st := StructType{} st.MyMethod1() st.MyMethod2() st.MyMethod2() 等同于 (&st).MyMethod2() ,是编译器给你做了 ------ st := &StructType{} st.MyMethod1() st.MyMethod2() 如果这样,你会发现编译不过去,因为 MyMethod1 并不是指针类型方法 ------ func (st StructType) MyMethod1() {} 等同于 func MyMethod1(st StructType) {} func (st *StructType) MyMethod2() {} 等同于 func MyMethod2(st *StructType) {} 如果传递结构体,会产生一个结构体的复制,而指针,只是指针变量的复制。 如果在里面有赋值操作: func (st StructType) MyMethod1() { st.Name = "name" } func (st *StructType) MyMethod2() { st.Name = "name" } MyMethod1 不会修改 st 本身;而 MyMethod2 会 这是所谓的 “副作用” 如何选择: ------ 绝大部分时间,选择指针方法。 对于小对象,只读对象,可以选择结构体方法。典型的比如 time.Time |
4
georgetso 2017-11-09 15:04:11 +08:00 1
还有一个区别:
The method set of any other named type T consists of all methods with receiver type T. The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T). |
5
qianguozheng 2017-11-09 15:16:07 +08:00
Good.
|
6
SuperMild 2017-11-09 15:58:36 +08:00
把这个看明白,Go 里的指针就完全理解了
https://blog.golang.org/laws-of-reflection |
7
motopig 2017-11-09 16:47:53 +08:00 1
```
package main import "fmt" type StructType struct { StructChildOne *StructChildTwo } type StructChildOne struct{} type StructChildTwo struct{} func (sto StructChildOne) One() { fmt.Println("child one method") } func (stt *StructChildOne) Towo() { fmt.Println("child two method sss") } func (stt *StructChildTwo) Two() { fmt.Println("child two method") } func (stt StructChildTwo) Twoo() { fmt.Println("child two method") } /*如果在 S 中包含一个嵌入类型 T,那么 S 和*S 的方法集合中都会包含接收者类型为 T 或*T 的所有方法 如果在 S 中包含一个嵌入类型*T,那么 S 和*S 的方法集合中只包含接收者类型为*T 的方法*/ func main() { var point = new(StructType) var point2 = StructType{} point.One() point.Towo() point2.One() point2.Two() point2.Twoo()// 这行会报错 } ``` |