公共,私人 - 大写,小写:
Posted
技术标签:
【中文标题】公共,私人 - 大写,小写:【英文标题】:Public, Private - Upper Case, Lower Case: 【发布时间】:2014-01-17 23:00:48 【问题描述】:GoLang 新手,来自 Delphi,C++:
我第一次尝试在 Go 中创建自己的包时,我按照有关如何布置工作区等的所有说明进行操作,但我不断收到编译器错误:
./myPackage.go:52: undefined: myFunc
经过一番探索,我发现 Go 中的公共访问修饰符只需通过以大写形式声明一个函数即可实现。太好了。
但是当我开始试验容器类时 - 对于初学者来说是 List
,我发现我必须像这样声明一个 List 引用返回值:
func GetFactors(value *int64) *list.List ...
*list
小写。
当我声明对列表的本地引用时也是如此 - 我必须使用:
l := list.New()
同样,list
的小写。
所以,我很困惑。规则是什么?列表调用和引用显然是公开的,否则我将无法调用/使用它们 - 那为什么它们是小写的?
【问题讨论】:
请注意,从 Go 1.5 开始,您还将获得半公共方法(在“内部”包中):在当前项目中导出,而不是用于外部项目。见my answer below 【参考方案1】:注意:从 Go 1.5(2015 年第二季度/第三季度)开始,您还将获得“受保护”导入(名为“内部”)!
见Go 1.4 doc:
Go 的包系统可以很容易地将程序构造成具有清晰边界的组件,但只有两种访问形式:本地(未导出)和全局(导出)。 有时人们希望拥有不导出的组件,例如,为了避免获取属于公共存储库一部分但不打算在其所属程序之外使用的代码接口的客户端。
Go 语言没有强制执行这种区别的能力,但是从 Go 1.4 开始,
go
命令引入了一种机制来定义“内部”包,这些包可能不会被它们所在的源子树之外的包导入.要创建这样的包,请将其放置在名为
internal
的目录或名为internal
的目录的子目录中。 当go
命令看到在其路径中包含internal
的包的导入时,它会验证执行导入的包是否位于以内部目录的父级为根的树中。 例如,包.../a/b/c/internal/d/e/f
只能通过以.../a/b/c
为根的目录树中的代码导入。 它不能通过.../a/b/g
或任何其他存储库中的代码导入。对于 Go 1.4,对主要 Go 存储库强制执行内部包机制;从 1.5 及以后的版本将对任何存储库强制执行。
【讨论】:
我不熟悉 Java 中的保护级别,但在 C# 中,protected
仅将成员公开给继承,internal
将成员公开给本地包。我认为一个成员应该完全隐藏,而不是在访问之前进行验证。【参考方案2】:
在本例中,list
是您通过import "container/list"
导入的包的名称,其公共成员为大写,如List
。
规则是公共函数、类型等都应该是大写的。
您可以根据需要为导入的包设置别名,但默认情况下它只是包路径最后一部分的名称——在本例中为list
。
更新:它不是包路径的最后一部分。这是实际的包名(通常是相同的)。
【讨论】:
知道了 - 谢谢。最让我感到困惑的是 list.New() - 例如在 C++ 中,它看起来像是对列表类型的调用 - 如果是这样,它就必须是公开的。所以你说它实际上是对包的引用,而 New() 是该包中的一个独立函数,它会自动返回一个 *List 引用,因为这就是 New() 在 list 包中所做的。说得通。还清除了文档中让我感到困惑的一些内容。 是的。文档实际上非常适合探索——函数名称点击源代码,这实际上有时比文档更有用。 :) golang.org/src/pkg/container/list/list.go?s=1662:1678#L52 仍然在文档中找到我的方式 - 但开始发现它们非常有用 - 你的回答会对我有很大帮助。 Go 具有欺骗性 - 它看起来像 C/C++,但实际上 非常 不同。【参考方案3】:注意:Go Spec for package name 没有提到包名总是小写。 它只声明它的名字由一个identifier 表示,它由一个“letter”的集合组成。
This thread 确实澄清了:
包名可以是任何名称,如果需要,可以以大写字母开头。 但是约定都是小写的,我想这样可以省去输入大写字母的麻烦。
大写/小写可导出性与包无关,因为您不能拥有私有包。
一旦你知道了,就更容易识别了:
list.New()
表示 constructor(始终在包级别,用于构建类型的初始化实例),例如 os.NewFile()
,
list.List
用于包列表的struct type(同一包的另一个结构类型为list.Element
)。
【讨论】:
以上是关于公共,私人 - 大写,小写:的主要内容,如果未能解决你的问题,请参考以下文章