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

Time:01-23

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.

  •  Tags:  
  • Related