【问题标题】:exposing a private type through a public function通过公共函数公开私有类型
【发布时间】:2013-03-18 01:43:39
【问题描述】:

当我通过公共函数暴露私有类型时,我正在测试 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有点相关,但它没有回答这个问题)

【问题讨论】:

    标签: types go visibility


    【解决方案1】:

    有效的陈述

    var f = pak.NewFoo("test")
    

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

    p := f.PakMethod()
    

    无效声明

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

    尝试获取struct foo 的地址。如果允许,这将允许您在 pak 包之外读取和写入 struct foo

    【讨论】:

    • 我不知道有匿名类型。但在pak 之外读/写struct foo 是有效的。它不是一个纯粹的匿名结构/接口,它和*pak.foo 完全一样,但是你不能写它,因为你看不到pak.foo。但是您必须了解pak.foo 的所有信息,因为您可以调用它的所有方法,在pak 的函数中使用pak.foo 类型的参数传递它或访问这些字段。这对我来说似乎很矛盾。我想暴露一个私有结构无论如何都没有多大意义。
    猜你喜欢
    • 1970-01-01
    • 2012-11-10
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 2011-03-03
    相关资源
    最近更新 更多