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)
}
CodePudding user response:
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.
CodePudding user response:
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.
CodePudding user response:
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.
