Go基础编程:方法(method)

原文链接http://oldchen.iwulai.com/index.php/2019/01/17/go%E5%9F%BA%E7%A1%80%E7%BC%96%E7%A8%8B%EF%BC%9A%E6%96%B9%E6%B3%95%EF%BC%88method%EF%BC%89/

1.基本概念

Go不像其它面相对象语言一样可以写个class,然后在class里面写一堆方法,但是它也很巧妙的实现了这种效果,我们只需要在普通函数前面加个接受者(receiver,写在函数名前面的括号里面),这样编译器就知道这个函数(方法)属于哪个struct了

method是附属在一个给定的类型上,语法和函数的声明语法几乎一样,只是再func后面增加了一个recevier(也就是method所依从的主体)

2.method定义

func (r ReceiverType) funcName(parameters) (results)

形象一点说,就是 ReceiverType 类型的所有字段,方法 funcName 都是可以使用的,可以认为 funcName 属于 ReceiverType

package main
import (
    "fmt"
    "math"
)
type Rectangle struct {
    width, height float64
}
type Circle struct {
    radius float64
}
func (r Rectangle) area() float64 {
    return r.width * r.height
}
func (c Circle) area() float64 {
    return c.radius * c.radius * math.Pi
}
func main() {
    r1 := Rectangle{12, 2}
    r2 := Rectangle{9, 4}
    c1 := Circle{10}
    c2 := Circle{25}
    fmt.Println("Area of r1 is: ", r1.area())//Area of r1 is:  24
    fmt.Println("Area of r2 is: ", r2.area())//Area of r2 is:  36
    fmt.Println("Area of c1 is: ", c1.area())//Area of c1 is:  314.1592653589793
    fmt.Println("Area of c2 is: ", c2.area())//Area of c2 is:  1963.4954084936207
}

method 是通过 . 来访问,就像访问struct里面字段一样。

method 里面可以访问接受者的字段,比如 r1.area() 就可以访问 r1 里面的 width 和 height。

虽然 method 的名字是一样的,但是不同的 receiver 不一样,那么 method 就不一样。这一点很重要哦

还有一点,method不仅能作用再struct上,也可以定义再任何自定义的类型、内置类型等各种类型上面。

method 中的 receiver 可以是值传递,也可以是指针。指针的话,就可以直接修改 receiver 中的内容。

3.method特性

  • Go中虽没有class,但依旧有method
  • 通过显示说明receiver来实现与某个类型的组合
  • 只能为同一个包中的类型定义方法
  • Receiver可以是类型的值或者指针
  • 不存在方法重载
  • 可以使用值或指针来调用方法,编译器会自动完成转换
  • 从某种意义上来说,方法是函数的语法糖,因为receiver其实就是方法所接收的第1个参数)
  • 如果外部结构和嵌入结构存在同名方法,则优先调用外部结构的方法
  • 类型别名不会拥有底层类型所附带的方法
  • 方法可以调用结构中的非公开字段

举例:

package main
import "fmt"  
type A struct {
    Name string
}

type B struct {
    Name string
}

func main() {
    a := A{}
    a.Print()
    fmt.Println(a.Name)

    b := B{}
    b.Print()
    fmt.Println(b.Name)
}

// 指针传递
func (a *A) Print() {
    a.Name = "AA"
    fmt.Println("A")
}

func (b B) Print() {
    b.Name = "BB"
    fmt.Println("B")
}

打印:

➜  myfirstgo go run method.go
A
AA
B

➜  myfirstgo

其他类型的方法绑定

type TZ int

func main() {
    var a TZ
    a.Print()
    fmt.Println(a)
}

func (a *TZ) Print() {
    fmt.Println("TZ")
}

打印:

➜  myfirstgo go run method.go
TZ
0

最后说下访问权限,因为Go是以大小写来区分是公有还是私有,但都是针对包级别的,所以在包内所有的都能访问,而方法绑定本身只能绑定包内的类型,所以方法可以访问接收者所有成员。如果是包外调用某类型的方法,则需要看方法名是大写还是小写,大写能被包外访问,小写只能被包内访问。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值