通过公共函数公开私有类型

时间:2013-03-27 19:41:09

标签: types go visibility

当我通过公共函数公开私有类型时,我正在测试go的类型可见性并收到意外行为:

package pak

type foo struct { // shoudn't be visible to any other package than pak
    Bar string
}

func NewFoo(str string) *foo {
    return &foo{str}
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

package main

import (
    "fmt"
    "pak"
)

func main() {
    // these lines should be equivalent...
    var f = pak.NewFoo("Hello, World!")         // this works fine...   
    var f *pak.foo = pak.NewFoo("Hello, World!") // ERROR: cannot refer to unexported name pak.foo

    fmt.Printf("%T\n", f)
    fmt.Printf("%s\n", f.Bar)  // how does it know about .Bar, if it can't see pak.foo?
}

如果没有明确声明f的类型,则会打印:

*pak.foo
Hello, World!

但是*pak.foo无法编译。

为什么两种情况都不会失败?

(这个question有点相关,但它没有回答这个问题)

1 个答案:

答案 0 :(得分:3)

有效声明

var f = pak.NewFoo("test")

为您提供struct foo的匿名隐藏地址。您无法使用它来读取或写入struct包之外的foo pak。您可以(通常会)使用它来调用pak包方法。例如,

p := f.PakMethod()

无效陈述

var f *pak.foo = pak.NewFoo("test")

尝试获取struct foo的地址。如果允许,这样您就可以在struct包裹之外阅读并写信foo pak