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 方法
相关推荐
微风中的麦穗3 小时前
【MATLAB】MATLAB R2025a 详细下载安装图文指南:下一代科学计算与工程仿真平台
开发语言·matlab·开发工具·工程仿真·matlab r2025a·matlab r2025·科学计算与工程仿真
2601_949146533 小时前
C语言语音通知API示例代码:基于标准C的语音接口开发与底层调用实践
c语言·开发语言
开源技术3 小时前
Python Pillow 优化,打开和保存速度最快提高14倍
开发语言·python·pillow
学嵌入式的小杨同学3 小时前
从零打造 Linux 终端 MP3 播放器!用 C 语言实现音乐自由
linux·c语言·开发语言·前端·vscode·ci/cd·vim
mftang5 小时前
Python 字符串拼接成字节详解
开发语言·python
jasligea5 小时前
构建个人智能助手
开发语言·python·自然语言处理
kokunka5 小时前
【源码+注释】纯C++小游戏开发之射击小球游戏
开发语言·c++·游戏
云栖梦泽6 小时前
易语言开发从入门到精通:补充篇·网络编程进阶+实用爬虫开发·API集成·代理IP配置·异步请求·防封禁优化
开发语言
java1234_小锋6 小时前
Java高频面试题:SpringBoot为什么要禁止循环依赖?
java·开发语言·面试
铅笔侠_小龙虾6 小时前
Flutter Demo
开发语言·javascript·flutter