可执行文件中的公共名称(“main”包)

huangapple go评论82阅读模式
英文:

Public names in an executable ("main" package)

问题

据我理解,当导入包时,首字母大写的名称会被导出(公开)。然而,由于可执行文件(即“main”包)是直接运行而不是被其他包导入的,那么名称是公开还是私有有什么区别呢?作为原则,我应该将所有名称都设为私有吗?

英文:

As I understand it, names that are capitalized are exported (public) when the package is imported. However, since executables ("main" packages) are run instead of being imported by other packages, what difference does it make whether names are public or not? Should I make all names private as a matter of principle?

答案1

得分: 1

简短回答是:这并不重要。也许在汇编级别上可能会有一个暴露的指针,但并没有明确说明。

实际上,关于godoc和公共(大写)字母的评论是错误的。对于可执行文件(package main),godoc只会打印包的//头部描述。它不会打印任何方法。我最近尝试了这个,不知道我的所有文档都去哪了。

相反,人们在package main应用程序中会添加一个名为doc.go的文件。由于godoc规范允许您在任何文件的任何位置装饰package main,您可以在这个doc.go文件中编写所有的文档,就像这样:

/* 这个可执行文件有一个特殊的目的
它在运行时打印Hello World。

在Go中编写注释的一个技巧是使用
换行符、文本、换行符来制作标题,
就像这样。

这是一个标题

子文本在这里。

还要注意,您可以创建缩进的
代码,使用4个空格...

像这样。
和这样。

上面的内容将以代码块的形式打印
在-html输出中。

*/
package main

请注意,上面的文本在文件末尾装饰了package main。这就是这个doc.go项目中的所有文本。

当您运行go doc .时,它将读取此文件并输出。

此外,当您运行主应用程序并使用-h或-help选项时,此文本也会呈现在控制台上。您可以根据需要进行详细说明,以帮助用户。

编辑:正如James提到的,是的,您可以导入其他主要包。但这与Go的惯用方式不符。Go的文档甚至说,为了可读性,复制代码是完全可以接受的。对我来说,这一点很难接受,因为我来自.NET并使用DRY原则。

英文:

The short answer is: it doesn't matter. Perhaps on an assembly level there may be an exposed pointer; but, it hasn't been stated.

And actually, the comments are wrong about godoc and public (capital) letters. For executables (package main), godoc only prints the package's // header description. It will not print any methods. I tried this recently and was wondering where all of my documentation was.

Instead, what people do for package main apps is to add a file called doc.go to their package. Since the godoc specification allows you to decorate the package main anywhere in any file, you would write all of your documentation here, in this doc.go file like so:

/* This executable serves a special purpose 
and that is say Hello World when it is run.

A tip for writing comments in go is to use 
line-break, text, line-break to make headers, 
like this.

This Is A Header

And the sub-text to the header goes here.

Also note that you can create indented 
code with 4 spaces...

   Like this.
   And this.

And the above will be printed as code
blocks in -html output.

*/
package main

Note that the text above decorates package main at the end of the file. That is all the text in this doc.go project.

When you run go doc ., it will read this file for the output.

Also, when you run the main app and use the -h or -help, this text is also rendered to the console. Make it as elaborate as you like to help users.

Edit: as James mentions, yes you can import other main packages. But that deverges from the idiomatic nature of Go in the first place. The docs at Go even say that duplicating code, in the interest of readability, is perfectly fine. That was hard for me to swallow too, coming from .NET and using DRY principals.

答案2

得分: 0

虽然这种情况不常见,但是可以从另一个包中导入名为main的包。考虑在一个Go工作空间中的以下文件:

src/foo/foo.go:

package main

import "fmt"

func Doit() {
    fmt.Println("Doit() 被调用")
}

func main() {
    fmt.Println("从 foo 调用 Doit")
    Doit()
}

src/bar/bar.go:

package main

import (
    "fmt"
    foo "foo"
)

func main() {
    fmt.Println("从 bar 调用 Doit")
    foo.Doit()
}

我可以像正常构建程序一样构建这两个程序,bar可以调用bar包中的导出函数。如果没有导出,这是不可能的。

这显然是一个人为的例子,但如果你有一系列相关的程序需要编译,这可能会有用。显然,将共享的代码拆分到一个不叫main的单独包中会更清晰。

英文:

While it is unusual, it is possible to import a package called main from another package. Consider the following files in a Go workspace:

src/foo/foo.go:

package main

import "fmt"

func Doit() {
    fmt.Println("Doit() called")
}

func main() {
    fmt.Println("Calling Doit from foo")
    Doit()
}

src/bar/bar.go:

package main

import (
    "fmt"
    foo "foo"
)

func main() {
    fmt.Println("Calling Doit from bar")
    foo.Doit()
}

I can build these two programs as normal, and bar can call the exported function from the bar package. If it wasn't exported, then this wouldn't be possible.

This is obviously a contrived example, but it could be useful if you have a collection of related programs you want to compile. Obviously, it would cleaner to split the shared code out into a separate package not named main.

答案3

得分: 0

我倾向于将在多个不同文件中使用的名称大写,而如果它们只是本地感兴趣的名称,则保持小写。

英文:

I tend to capitalize names that are used in several different files, and leave them lowercase if they are only of local interest.

答案4

得分: 0

我在Discord Gophers上提问,Gopher Herder @LethalClips#4645 给了我一个合适的答案。

> 当你需要让像 encoding/json 这样的库从外部读取时,通常只会在主包中导出东西,因为你不想手动导入主包。

这个答案帮助我解决了问题。如果被库访问到,就导出它。

英文:

I asked on Discord Gophers, and Gopher Herder @LethalClips#4645 had an appropriate answer for me.

> You generally will only be exporting things in the main package when you need them to be read externally by libraries like encoding/json, as you don't want to be manually importing the main package.

This answer helped me to sort it out. If it's accessed by a library, export it.

huangapple
  • 本文由 发表于 2014年7月31日 10:55:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/25050128.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定