美文网首页
Go 函数值接收者和指针接收者

Go 函数值接收者和指针接收者

作者: quanCN | 来源:发表于2021-08-18 20:17 被阅读0次

    值接收者和指针接收者

    • 值接收者
      使用值接收者声明方法,调用者会用这个值的一个副本来执行
    • 指针接收者
      使用指针接收者声明方法,这类方法会共享调用方法时接收者所指向的值
    • 值接收者和指针接收者比较
      type Book struct {
          id int;name string;price float64
      }
      //使用值接收者 实现方法
      func (receiver Book) fun1()  {
          receiver.name = "abc1"
      }
      //使用指针接收者 实现方法
      func (receiver *Book) fun2()  {
          receiver.name = "abc2"
      }
      func main() {
          book := &Book{id: 1,name: "Think in java",price: 99.99}
          fmt.Println(book)
          book.fun1()
          fmt.Println(book)
          book.fun2()
          fmt.Println(book)
      }
      

    结构类型

    结构类型可以分为原始类型和非原始类型

    • 原始类型
      对该类型做增加或者删除的操作时,该结构类型的值不应该被更改,例如Time类型
      type Time struct {
          wall uint64
          ext  int64
      
          loc *Location
      }
      
      来看一下Time类型的一些方法
      func (t Time) Add(d Duration) Time {
          dsec := int64(d / 1e9)
          nsec := t.nsec() + int32(d%1e9)
          if nsec >= 1e9 {
              dsec++
              nsec -= 1e9
          } else if nsec < 0 {
              dsec--
              nsec += 1e9
          }
          t.wall = t.wall&^nsecMask | uint64(nsec) // update nsec
          t.addSec(dsec)
          if t.wall&hasMonotonic != 0 {
              te := t.ext + int64(d)
              if d < 0 && te > t.ext || d > 0 && te < t.ext {
                  // Monotonic clock reading now out of range; degrade to wall-only.
                  t.stripMono()
              } else {
                  t.ext = te
              }
          }
          return t
      }
      
      这个方法使用值接收者,并返回了一个新的Time值。该方法操作的是调用者传入的Time值的副本,并且给调用者返回了一个方法内的Time值的副本
    • 非原始类型
      对这个类型的值做增加或者删除的操作应该更改值本身,例如File类型
      type File struct {
          *file // os specific
      }
      
      来看一下File类型的一些方法
      func (f *File) Chdir() error {
          if err := f.checkValid("chdir"); err != nil {
              return err
          }
          if e := f.pfd.Fchdir(); e != nil {
              return f.wrapErr("chdir", e)
          }
          return nil
      }
      
      该方法即使没有修改接收者的值,依然是用指针接收者来声明的,因为File类型的值具备非原始的本质,所以总是应该被共享,而不是被复制

    如何选择值接收者和指针接收者

    是使用值接受者还是指针接受者,不应该由该方法是否修改了接收到的值来决定,而是由该类型的本质决定

    相关文章

      网友评论

          本文标题:Go 函数值接收者和指针接收者

          本文链接:https://www.haomeiwen.com/subject/nbknbltx.html