根据《Go语言程序设计》一书,将”main”包作为库导入。

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

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

问题

在《The Go Programming Language》的第308页上,它说:

> 一个名为main的包通常会生成一个可执行程序,但它也可以作为库导入。

但是当我尝试时,我得到了一个错误:imp.go:5:5: import "foo" is a program, not an importable package

那么...他们在说什么?如何将一个main包导入为库?

我的试验代码只是:

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)
}
英文:

On page 308 of The Go Programming Language, it says

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

But when I try it, I get an error: imp.go:5:5: import "foo" is a program, not an importable package

So...what are they talking about? How can you import a main package as a library?

My trial code is just:

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)
}

答案1

得分: 4

相关:从其他包访问主要包

我最好的猜测是,当这本书写的时候,这是正确的,但现在已经变得不可能了。golang/go#4210 是相关的问题,看起来停止它工作的变化发生在2015年中期,而这本书仅在几个月后出版。

英文:

Relevant: Access main package from other package

My best guess is that this was true when the book was written, but has since been made impossible. golang/go#4210 is the relevant issue and it seems the change that stopped it from working landed in mid-2015 while the book was published only a few months after.

答案2

得分: 0

确实,Go代码可以有一个main函数并作为包导入,但不包括包含"main"函数的包。我建议将所有业务代码放在一个单独的包中(例如,一个子目录中),而主包只做最少的事情(例如初始化应用程序和阻塞)。这样,您可以导入代码的任何包,除了主包。

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

英文:

It is true that go code can have a main and be imported as a package, but not the package containing the "main" function. What I suggest is to put all your business code in a separate package (e.g, in a sub-directory) and have the main package doing minimal things (initializing your app and blocking for instance). This way you can import any of your code's package, except main package.

However as a good practice, if you have a repository with a program which you want to import some code of, I'd suggest you to make a different repository for this code to make it an independent library.

答案3

得分: -1

似乎可以在同一个包的测试中导入“main”包。

在文件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是由fstanis提到的。

英文:

It appears that it's possible to import the "main" package from a test for the same package.

With a file foo/foo_test.go:

package main_test

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

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

This works. Notice the import path "foo" results in a identifier main.

Since the statement appeared in the chapter on testing, they must have meant "it can be imported as a library too IN TESTS", but they left out that condition!

As far as I can tell, the situation when the book was published (Go version 1.5) was the same as it is now (Go version 1.17), since the change 10925 referred to by fstanis.

huangapple
  • 本文由 发表于 2022年1月23日 01:40:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/70815458.html
匿名

发表评论

匿名网友

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

确定