go interface 惯用法

先看关于struct方法 receiver 是对象还是指针的问题

type ISth interface {
    getInfo() string
}
type Person struct {
    Name string
}
func (p Person) getInfo() string { // 注:这里是对象
    return p.Name
}
func main() {
    var sth ISth
    sth = Person{Name: "felix"}   // 变量赋值是合法的
    sth = &Person{Name: "felix"}  // 指针赋值也同样合法
    fmt.Println(sth)
}

如果 receiver是对象, 接口变量既可以是对象, 也可以是对象指针, 我猜想原因是指针变量也是.操作符,

另外要注意, 两次sth赋值后效果是不同的, 指针赋值并没有发生整个Person变量的值拷贝


func main() {
	var sth ISth
	p1 := &Person{Name: "p1"}       // p1 值指针
	p2 := Person{Name: "p2"}        // p2 是对象
	sth = p1                        // sth 与 p1 指向同一片内存
	p1.Name = "p1 is changed"       // p1 的 Name 修改了
	fmt.Println(sth.getInfo())      // sth 下的 Name 同样也修改了, 打印出 "p1 is changed"
	sth = p2                        // 整个p2对象发生了值拷贝, sth与p2代表的是两片内存
	p2.Name = "p2 is changed"       // 只是修改了p2对象的Name值
	fmt.Println(sth.getInfo())      // sth 并没有被影响, 打印出 "p2"
}

但如果receiver是指针,那么接口变量只能是对象指针了, 对象赋值将会编译不过

type ISth interface {
	getInfo() string
}
type Person struct {
	Name string
}
func (p *Person) getInfo() string {      // 注: 这里是指针
	return p.Name
}
func main() {
	var sth1, sth2 ISth
	sth1 = &Person{Name: "felix"}        // 可以
	sth2 = Person{Name: "mary"}          // 编译报错
	fmt.Println(sth1, sth2)
}

个人理解通常情况下receiver是指针比较合理, 这样在定义interface变量时, 就可以直接使用变量, 并被赋值为struct的指针, 当interface 作为变量传参或变量间赋值时, 直接使用interface变量本身, 不需要在取地址用指针了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值