go 方法 —— 摘自go语言学习笔记

本文深入探讨了Go语言中方法与接收者的选择原则,包括如何根据对象大小、是否需要修改状态、引用类型等因素来决定使用值接收者还是指针接收者。同时,文章还解释了方法集的概念,以及如何通过表达式和值两种状态调用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 如何选择方法的receiver类型:要修改实例状态,用 *T;无须修改状态的小对象或固定值,建议用T;大对象建议用 *T,以减少复制成本;引用类型、字符串、函数等指针包装对象,直接用T;若包含Mutex等同步字段,用 *T,避免因复制造成锁操作无效;其他无法确定的情况,都用 *T
  2. 方法集:类型T方法集包含所有receiver T方法;类型*T方法集包含所有receiver T + *T 方法;匿名嵌入S,T方法集包含所有receiver S方法;匿名嵌入 *S,T方法集包含所有receiver S + *S方法;匿名嵌入 S 或 *S,*T方法集包含所有receiver S + *S方法
  3. 方法和函数一样,除直接调用外,还可赋值给变量,或作为参数传递。依照具体引用方式的不同,可分为expression和value两种状态
    3.1 通过类型引用的method expression会被还原为普通函数样式,receiver是第一参数,调用时必须显式传参
    type N int
    func (n N) test() {
    	fmt.Printf("test.n:%p,%d\n",&n,n)
    }
    func main() {
    	var n N = 25
    	fmt.Println("main.n:%p,%d\n",&n,n)
    
    	f1:=N.test          //func(n N)
    	f1(n)
    
    	f2:=(*N).test       //func(n *N)
    	f2(&n)              //按方法集中的签名传递正确类型的参数
    }
    // 输出:
    // main.n:0xc82000a140,25
    // test.n:0xc82000a158,25
    // test.n:0xc82000a168,25
    // 尽管 *N方法集包装的test方法receiver类型不同,但是编译器会保证按原定义类型拷贝传值
    
  4. 只能为当前包内命名类型定义方法
  5. 可以像字段成员那样访问匿名字段方法,编译器负责查找
    type User struct {
    id int
    name string
    }
    type Manager struct {
        User
    }
    func (self *User) ToString() string { // receiver = &(Manager.User)
        return fmt.Sprintf("User: %p, %v", self, self)
    }
    func main() {
        m := Manager{User{1, "Tom"}}
    
        fmt.Printf("Manager: %p\n", &m)
        fmt.Println(m.ToString())
    }
    // Manager: 0x2102281b0
    // User : 0x2102281b0, &{1 Tom}
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值