登录
首页 >  Golang >  Go问答

改变 go 中接收器结构的值类型为指针类型是否兼容向后?

来源:stackoverflow

时间:2024-03-25 21:03:37 274浏览 收藏

在 Go 中,改变接收器结构的值类型为指针类型通常是向后兼容的,无需增加主版本号。然而,在某些情况下,这种改变可能会破坏现有代码,例如:当接收器不可寻址、存在接口时或方法接收值类型的副本。另一方面,将指针接收器更改为值接收器通常是安全的,因为它不会引入编译错误,但会改变方法的语义。

问题内容

从如下代码开始:

type Foo struct {
    V bool
}

func (f Foo) bar() bool {
    return f.V
}

是否允许在不增加主版本号的情况下更改为 func (f *foo) bar() bool ?也就是说,假设您知道您的类型不存在线程安全问题。如果是这样,反向更改也是允许的,对吗?

据我所知,无论变量是值还是指针,调用该函数的任何代码都将在两次更改后继续编译并按预期工作。


正确答案


根据评论,this answer 答案提供了很好的总结 t*t 接收器类型。以下是几个示例,其中从 func (f foo) bar() bool 更改为 func (f *foo) bar() bool 会破坏现有代码。

示例 1:t 不可寻址 (playground):

type foo struct {
    v bool
}

func (f *foo) bar() bool { // change to `(f foo)` and this will work
    return f.v
}

func x() foo {
    return foo{true}
}

func main() {
    fmt.printf("%v", x().bar())
}

示例 2:接口 (playground):

type foo struct {
    v bool
}

func (f *foo) bar() bool { // change to `(f foo)` and this will work
    return f.v
}

type fooer interface {
    bar() bool
}

func main() {
    var x fooer
    x = foo{}
    fmt.println(x.bar())
}

如果对于 foo 类型,您有一个带有值接收器的方法:

func (f foo) method() {...}

然后为 foo*foo 定义此方法,并且对于这两种情况,该方法都会接收 foo 实例的副本。如果您将其更改为:

func (f *Foo) Method() {...}

那么 foo.method 仅适用于 *foo,不适用于 foo。因此,这样的更改可能会导致编译错误。

如果您有一个用指针接收器声明的方法,现在您将其更改为值接收器,则您可以为 foo*foo 声明该方法,因此不应出现编译错误。该方法的语义也会发生变化,因为现在 method 将收到 foo 实例的副本,即使该实例是可寻址的,或者它是一个指针。

理论要掌握,实操不能落!以上关于《改变 go 中接收器结构的值类型为指针类型是否兼容向后?》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>