【问题标题】:Are pointers dereferenced by default inside of methods?默认情况下,指针是否在方法内部取消引用?
【发布时间】:2015-08-27 11:14:18
【问题描述】:

我对 Go 结构中的方法感到困惑。我在他们有的教程中跟随:

func (p *Page) save() error {
    filename := p.Title + ".txt"
    return ioutil.WriteFile(filename, p.Body, 0600)
}

据我了解,p 是指针,您需要在检索属性之前取消对指针的引用:

filename := (*p).Title + ".txt"

这对我来说有意义的唯一方法是,如果点在 C++ 中表现得像 ->。我错过了什么?

【问题讨论】:

  • 我不知道你为什么被否决,接受我的投赞成票。

标签: pointers go


【解决方案1】:

是的,指向结构的指针会自动取消引用。来自spec on selectors

以下规则适用于选择器:

  1. 对于T*T 类型的值x,其中T 不是指针或接口类型,x.f 表示T 中最浅深度的字段或方法 哪里有这样的f。如果不完全是一个f 最浅的深度,选择器表达式是非法的。

...

  1. 作为一个例外,如果x 的类型是命名指针类型并且(*x).f 是表示字段的有效选择器表达式(但不是 方法),x.f(*x).f 的简写。

因此,以下两种说法相同(首选第一种):

filename := p.Title + ".txt"
filename := (*p).Title + ".txt"

【讨论】:

    【解决方案2】:

    您不必引用指针或使用特殊的访问运算符来访问 Go 中结构的字段。

    myRef := &ILikeCompositeLiteralInitilization{}
    fmt.Println(myRef.Dereferenced);
    

    在功能上等同于;

    fmt.Printn((*myRef).Dereferenced);
    

    可能值得注意的是,函数的行为不是这样的。意思是,我必须取消引用才能调用接收类型是值而不是指针的方法。即;

    func (*ILikeCompositeLiteralInitilization) PointerVersion()
    func (ILikeCompositeLiteralInitilization) ValueVersion()
    
    myRef.PointerVersion() // compiler likes this
    
    myRef.ValueVersion() // won't compile
    
    (*myRef).ValueVersion() // compiler is OK with this
    

    基本上,如果函数不会发生隐式取消引用或地址类型操作,您的代码将无法编译。

    【讨论】:

    • 您确定myRef.ValueVersion() // won't compile 吗?从我在其他地方读到的there's "magic" happening that allows you to call a method with a pointer receiver on a non-pointer value and vice versa。我已经测试了你的用例并且它有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    相关资源
    最近更新 更多