V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zjsxwc
V2EX  ›  程序员

GO 语言的指针使用规范是什么?

  •  1
     
  •   zjsxwc ·
    zjsxwc · 2017-11-09 14:51:12 +08:00 · 3539 次点击
    这是一个创建于 2573 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在定义 struct 的 method 时, 好像这这两种方式没有区别:

    
    func (st StructType) MyMethod1() {}
    
    func (st *StructType) MyMethod2() {}
    
    

    而且调用访问时好像, 也没区别:

    
    st := StructType{}
    st.MyMethod1()
    st.MyMethod2() 
    
    

    于是我就困惑了, 我看了 github 上主流的几个项目, 好像都倾向于使用MyMethod2这种接收者为指针类型的定义方式, 很少见到MyMethod1的方式, 这里有什么规范吗?

    第 1 条附言  ·  2017-11-09 18:01:48 +08:00
    学习了,总结了大家的回复,就是用指针作为方法的接收者可以规避掉很多 golang 里的坑
    7 条回复    2017-11-09 16:47:53 +08:00
    rrfeng
        1
    rrfeng  
       2017-11-09 14:56:12 +08:00
    boboliu
        2
    boboliu  
       2017-11-09 15:02:53 +08:00 via Android
    为什么不试试 st := &StructType{} 呢?
    cloudzhou
        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
    georgetso
        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).
    qianguozheng
        5
    qianguozheng  
       2017-11-09 15:16:07 +08:00
    Good.
    SuperMild
        6
    SuperMild  
       2017-11-09 15:58:36 +08:00
    把这个看明白,Go 里的指针就完全理解了
    https://blog.golang.org/laws-of-reflection
    motopig
        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()// 这行会报错
    }
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1044 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 19:39 · PVG 03:39 · LAX 11:39 · JFK 14:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.