导入 "main" 包作为库(根据 _ The Go Programming Language)

Importing "main" package as a library (According to _The Go Programming Language_)

The Go Programming Language 的第 308 页,它说

A package named main ordinarily produces an executable program, but it can be imported as a library too.

但是当我尝试时,出现错误:imp.go:5:5: import "foo" is a program, not an importable package

所以...他们在说什么?如何将主包导入为库?

我的试用码是:

imp.go

package main

import (
    "fmt"
    "foo"
)

func main() {
    fmt.Println(foo.Hi)
}

foo/foo.go

package main

import "fmt"

var Hi int = 3

func main() {
    fmt.Printf("Hi %d!\n", Hi)
}

相关:

我最好的猜测是,这本书在写的时候是真的,但后来就不可能了。 golang/go#4210 是相关问题,似乎阻止它工作的更改出现在 2015 年年中,而这本书仅在几个月后才出版。

go 代码确实可以有一个 main 并作为一个包导入,但不是包含“main”函数的包。我的建议是将您所有的业务代码放在一个单独的包中(例如,在 sub-directory 中)并让主包做最少的事情(例如初始化您的应用程序和阻塞)。这样你就可以导入你的任何代码包,除了主包。

然而,作为一个好的做法,如果您有一个存储库,其中包含您想要导入其某些代码的程序,我建议您为该代码创建一个不同的存储库,使其成为一个独立的库。

似乎可以从同一包的测试中导入“主”包。

有文件foo/foo_test.go:

package main_test

import (
    "fmt"
    "foo"
    "testing"
)

func TestFoo(t *testing.T) {
    fmt.Println(main.Hi)
}

这行得通。请注意导入路径“foo”导致标识符 main.

由于测试章节中出现了声明,他们的意思肯定是“它也可以在测试中作为库导入”,但他们忽略了那个条件!

据我所知,本书出版时(Go 1.5 版)的情况与现在(Go 1.17 版)一样,因为 change 10925 referred to .