• golang receiver of method方法接收者


    什么是method(方法)?method是函数的另外一种形态,隶属于某个类型的方法。

    method的语法:

    func (r Receiver) funcName (parameters) (result)

    receiver可以看作是method的第一个参数,method并且支持继承和重写。

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

    • 方法有一个值类型和指针类型的接受者时,都可以直接调用,内部会
    自动进行语法的转换。

    package main
    
    import (
        "fmt"
    )
    
    type A struct {
        Name string
    }
    
    type B struct {
        Name string
    }
    
    func main() {
        //Receiver 可以是类型的值或者指针
        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...")
    }
    提阶,方法也支持提阶
        emp1 := Employee{
            name:     "张三",
            salary:   6000,
            currency: "$",
            age:      18,
            Address:  Address{"山东", "济南"},
        }
        //提阶
        emp1.fullAddress()         //山东 济南,提阶相当于直接访问Address里的
        emp1.Address.fullAddress() //山东 济南
    非结构类型的方法

    非结构体类型也可以定义方法,不过这里需要注意一点。为了定义某个类型的方法,接收者类型的定义与方法的定义必须在同一个包中。

    因为必须在一个包中而int则在main包中我们没法去定义这个里为了简单直观,给int声明了别名

     
    //非结构体方法扩展
    type myInt int
    
    func (a myInt) add(b myInt) myInt {
        return a + b
    }
    func main() {
        //调用扩展的方法
        num1 := myInt(5)
        num2 := myInt(10)
        sum := num1.add(num2)
        fmt.Println("Sum is", sum)
    
    }
    package main
    
    import (
        "fmt"
        "math"
    )
    
    //Employee 需要添加注释或者改成非导出变量(首字母小写)
    type Employee struct {
        name     string
        currency string
        salary   int
        age      int
        Address
    }
    
    //Address 代码规范
    type Address struct {
        city  string
        state string
    }
    
    //Rectangle 代码规范
    type Rectangle struct {
        width  float32
        height float32
    }
    
    //Circle 代码规范
    type Circle struct {
        radius float32
    }
    
    //Employee 的方法
    func (e Employee) displaySalary() {
        fmt.Println(e)
    }
    func (e Employee) changeName(newName string) {
        e.name = newName
    }
    func (e *Employee) changeAge(newAge int) {
        e.age = newAge
    }
    
    //Address 的方法
    func (add Address) fullAddress() {
        fmt.Println(add.city, add.state)
    }
    
    //Rectangle 的方法计算面积
    func (r Rectangle) getArea() float32 {
        return r.width * r.height
    }
    
    //Circle  的方法
    func (c Circle) getArea() float32 {
        return math.Pi * c.radius * c.radius
    }
    
    //非结构体方法扩展
    type myInt int
    
    func (a myInt) add(b myInt) myInt {
        return a + b
    }
    func main() {
        //调用方法
        emp1 := Employee{
            name:     "张三",
            salary:   6000,
            currency: "$",
            age:      18,
            Address:  Address{"山东", "济南"},
        }
        emp1.displaySalary()
    
        fmt.Println("Before call changeName ", emp1.name)
        //修改名字,未发生变化因为是值传递
        emp1.changeName("zhangsan")
        fmt.Println("After call changeName ", emp1.name) //After call changeName  张三
    
        fmt.Println("Before change age", emp1.age)
        //利用指针来修改年龄
        emp1.changeAge(50)
        fmt.Println("After change age", emp1.age) //After change age 50
    
        //提阶
        emp1.fullAddress()         //山东 济南,提阶相当于直接访问Address里的
        emp1.Address.fullAddress() //山东 济南
    
        //计算面积
        re := Rectangle{20, 30}
        c := Circle{40}
        //两个类型调用同名方法
        fmt.Println(re.getArea())
        fmt.Println(c.getArea())
    
        //调用扩展的方法
        num1 := myInt(5)
        num2 := myInt(10)
        sum := num1.add(num2)
        fmt.Println("Sum is", sum)
    
    }
     
  • 相关阅读:
    资深技术Leader曹乐:如何成为技术大牛
    深入理解golang: interface
    Redis主体流程分析
    为什么我们总爱讨论技术与业务之间的那些是是非非?
    [产品]九卷读书:产品的视角-产品思维框架
    go http server 编程实践及源码分析
    [产品]九卷读书: 产品的视角-产品经理能力模型
    [产品]:腾讯8分钟产品课
    Golang gRPC学习(02): 编写helloworld服务
    括号生成
  • 原文地址:https://www.cnblogs.com/youxin/p/16220828.html
Copyright © 2020-2023  润新知