• go方法集


    方法集

    Golang方法集 :每个类型都有与之关联的方法集,这会影响到接口实现规则。

        • 类型 T 方法集包含全部 receiver T 方法。
        • 类型 *T 方法集包含全部 receiver T + *T 方法。
        • 如类型 S 包含匿名字段 T,则 S 和 *S 方法集包含 T 方法。 
        • 如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 T + *T 方法。 
        • 不管嵌入 T 或 *T,*S 方法集总是包含 T + *T 方法。
    

    用实例 value 和 pointer 调用方法 (含匿名字段) 不受方法集约束,编译器总是查找全部方法,并自动转换 receiver 实参。

    Go 语言中内部类型方法集提升的规则:

    类型 T 方法集包含全部 receiver T 方法。

    package main
    
    import (
        "fmt"
    )
    
    type T struct {
        int
    }
    
    func (t T) test() {
        fmt.Println("类型 T 方法集包含全部 receiver T 方法。")
    }
    
    func main() {
        t1 := T{1}
        fmt.Printf("t1 is : %v\n", t1)
        t1.test()
    }
    

    输出结果:

        t1 is : {1}
        类型 T 方法集包含全部 receiver T 方法。
    

    类型 *T 方法集包含全部 receiver T + *T 方法。

    package main
    
    import (
        "fmt"
    )
    
    type T struct {
        int
    }
    
    func (t T) testT() {
        fmt.Println("类型 *T 方法集包含全部 receiver T 方法。")
    }
    
    func (t *T) testP() {
        fmt.Println("类型 *T 方法集包含全部 receiver *T 方法。")
    }
    
    func main() {
        t1 := T{1}
        t2 := &t1
        fmt.Printf("t2 is : %v\n", t2)
        t2.testT()
        t2.testP()
    }
    

    输出结果:

        t2 is : &{1}
        类型 *T 方法集包含全部 receiver T 方法。
        类型 *T 方法集包含全部 receiver *T 方法。
    

    给定一个结构体类型 S 和一个命名为 T 的类型,方法提升像下面规定的这样被包含在结构体方法集中:

    如类型 S 包含匿名字段 T,则 S 和 *S 方法集包含 T 方法。

    这条规则说的是当我们嵌入一个类型,嵌入类型的接受者为值类型的方法将被提升,可以被外部类型的值和指针调用。

    package main
    
    import (
        "fmt"
    )
    
    type S struct {
        T
    }
    
    type T struct {
        int
    }
    
    func (t T) testT() {
        fmt.Println("如类型 S 包含匿名字段 T,则 S 和 *S 方法集包含 T 方法。")
    }
    
    func main() {
        s1 := S{T{1}}
        s2 := &s1
        fmt.Printf("s1 is : %v\n", s1)
        s1.testT()
        fmt.Printf("s2 is : %v\n", s2)
        s2.testT()
    }
    

    输出结果:

        s1 is : {{1}}
        如类型 S 包含匿名字段 T,则 S 和 *S 方法集包含 T 方法。
        s2 is : &{{1}}
        如类型 S 包含匿名字段 T,则 S 和 *S 方法集包含 T 方法。
    

    如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 T + *T 方法。

    这条规则说的是当我们嵌入一个类型的指针,嵌入类型的接受者为值类型或指针类型的方法将被提升,可以被外部类型的值或者指针调用。

    package main
    
    import (
        "fmt"
    )
    
    type S struct {
        T
    }
    
    type T struct {
        int
    }
    
    func (t T) testT() {
        fmt.Println("如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 T 方法")
    }
    func (t *T) testP() {
        fmt.Println("如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 *T 方法")
    }
    
    func main() {
        s1 := S{T{1}}
        s2 := &s1
        fmt.Printf("s1 is : %v\n", s1)
        s1.testT()
        s1.testP()
        fmt.Printf("s2 is : %v\n", s2)
        s2.testT()
        s2.testP()
    }
    

    输出结果:

        s1 is : {{1}}
        如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 T 方法
        如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 *T 方法
        s2 is : &{{1}}
        如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 T 方法
        如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 *T 方法
    

  • 相关阅读:
    关于.Net 7.0 RC gRPC JSON 转码为 Swagger/OpenAPI文档的注意事项
    图像的几何变换(缩放、平移、旋转)
    Python之时间模块和随机模块
    CSS 动画一站式指南
    细胞实验文献检索——PubMed | MedChemExpress
    智能微秘书+FastGPT,打造你的超级微信助手!
    Linux安装Nginx并配置启动命令
    大模型prompt提示词如何调优?
    Json、JDBC
    SATA系列专题之六:浅析NCQ原生指令序列
  • 原文地址:https://blog.csdn.net/tiancityycf/article/details/138665230