Go语言编程基础 方法与接口(一)——方法、指针接收者

1 方法

Go没有类,但是可以为结构体类型定义方法。
方法就是一类带特殊的接收者参数的函数。
方法接收者在它自己的参数列表内,位于func关键字和方法名之间。

package main

import "fmt"

type sss struct{
  aa, bb int
}

func (s sss) mmm() {
  fmt.Println(s.aa, s.bb)
}

func main() {
  ooo := sss{12, 34}
  ooo.mmm()
}

note:方法mmm具有一个名为s类型为sss的接收者。

也可以为非结构体类型声明方法。
接收者的类型定义和方法声明必须在同一包内,不能为内置类型声明方法。

package main

import "fmt"

type iii int

func (i iii) fff() {
  fmt.Println(i)
}
func main()  {
  i := iii(12)
  i.fff()
}

2 方法即函数

方法本身就是一个正常的函数,功能并没有什么变化。

3 指针接收者

可以为指针类型的接收者声明方法,这意味着对于类型T,接收者类型可以使用文法T。(此外,T不能是类似于int这样的指针)

指针接收者的方法可以修改指针指向的值,由于方法经常需要修改它的接收者,所以指针类型的接收者比值类型的接收者更常用。

如果使用值接收者,方法会对原始接收者的副本进行操作。

package main

import "fmt"

type vvv struct {
  xx, yy int
}

func (p *vvv) pf() {
  p.xx = 111
  p.yy = 111
  
}

func (v vvv) vf() {
  v.xx = 111
  v.yy = 222
}

func main()  {
  v := vvv{999, 999}
  fmt.Println(v)

  v.vf()
  fmt.Println(v)

  v.pf()
  fmt.Println(v)
}

4 方法与指针重定向

带指针参数的函数必须接受一个指针,而以指针为接收者的方法被调用时,接收者既能为值又能为指针。

package main

import "fmt"

type vv struct{
  x, y int
}

func (v *vv) sm(f int) {
  v.x = v.x * f
  v.y = v.y * f
}

func sf(v *vv, f int) {
  v.x = v.x * f
  v.y = v.y * f
}

func main() {
    v := vv{3, 4}
    v.sm(2)
    sf(&v, 10)
    fmt.Println(v)

    p := vv{4, 3}
    p.sm(3)
    sf(p, 8)
    fmt.Println(p) 
}

相同的事情也发生在相反的方向。
接受值作为参数的函数必须接受指定类型的值,不能接收指针。
以值为接收者的方法被调用时,接收者既能为值又能为指针。

package main

import (
  "fmt"
  "math"
)

type vv struct{
  x, y float64
}

func (v vv) abs() float64 {
  return math.Sqrt(v.x*v.x + v.y*v.y)
}

func absf(v vv) float64 {
  return math.Sqrt(v.x*v.x + v.y*v.y)
}

func main() {
  v := vv{3, 4}
  fmt.Println(v.abs())
  fmt.Println(absf(v))

  p := &vv{3, 4}
  fmt.Println(v.abs())
  fmt.Println(absf(*p))
}

5 选择值或指针作为接收者

使用指针接收者的原因有二:
首先,方法能够修改器接收者指向的值
其次,这样可以避免在每次调用方法时复制该值,提高效率

通常来说,所有给定类型的方法都应该有值或指针接收者,但是并不应该将二者混用。

扫描二维码关注公众号,回复: 4094598 查看本文章

学习源:Go 指南

猜你喜欢

转载自blog.csdn.net/qq_32165041/article/details/83894261