Suppose I have a package folder as below:
hello
|---main.go
|---utilities.go
In the main.go
, I have:
package main
In the utilities.go
, I have:
package hello
I did this because:
main.go
file.hello
folder.But when I run go list hello
, it gives me this:
can't load package: package hello: found packages main (main.go) and hello (utilities.go) in E:\Workbench\Go\src\hello
Then I remove the utilities.go
and tried the go list hello
again with only main.go
. It gives me this:
hello
So do I have to move all the utilities to another package folder?
Do I have to keep only the single main.go
in the hello package folder because it seems it doesn't get along well with other package names?
An useful ref: http://thenewstack.io/understanding-golang-packages/
After a few brief experiments, I guess the import yyy
decides the link search path while the package xxx
declaration decides the exported symbol name in the compiled .a
file.
Because I noticed these facts:
package xxx
declaration doesn't have to be the same as the containing package folder name, say yyy
.import yyy
declaration must use the package folder path yyy
.xxx.Symbol
rather than yyy.Symbol
.To confirm my guess in ADD 2, I did this:
(pkg1\file1.go)
package pkg2 // I deliberately use a different pkg name "pkg2" rather than the folder name "pkg1"
import "fmt"
func FA() {
fmt.Println("in the pkg2.FA")
}
(cmd1\main.go)
package main
import "pkg1"
func main() {
pkg2.FA() //here, the FA is referenced via "pkg2" rather than the "pkg1".
}
The above 2 files can compile and run.
But if I changed to this:
(cmd1\main.go)
package main
import "pkg1"
func main() {
pkg1.FA() //here, the FA is referenced via "pkg1" as in the import statement. Should work, isn't it?
}
This will give:
....\src\cmd1\main.go:3: imported and not used: "pkg1" as pkg2
....\src\cmd1\main.go:6: undefined: pkg1 in pkg1.FA
And to double confirm, I checked the compiled pkg1.a
file with go tool nm pkg1.a
, I didn't see package name affects the exported symbols. (btw, the GNU nm tool seems not be able to recognize the golang .a
file format.)
U
515 T %22%22.FA <========== this is my fuction FA
67b R %22%22.FA·f <========== this is my fuction FA
5eb T %22%22.init
67b B %22%22.initdone·
683 R %22%22.init·f
U fmt.Println
U fmt.init
673 R gclocals·33cdeccccebe80329f1fdbee7f5874cb
66b R gclocals·69c1753bd5f81501d95132d08af04464
65b R gclocals·e29b39dba2f7b47ee8f21f123fdd2633
64d R go.string."in the pkg2.FA"
63d R go.string.hdr."in the pkg2.FA"
7d2 R go.typelink.*[1]interface {}
796 R go.typelink.[1]interface {}
737 R go.typelink.[]interface {}
U runtime.algarray
U runtime.convT2E
6ec R runtime.gcbits.01
68b R runtime.gcbits.03
U runtime.morestack_noctxt
U runtime.throwinit
79a R type.*[1]interface {}
7d6 R type..importpath.fmt.
73b R type..namedata.*[1]interface {}.
6ed R type..namedata.*[]interface {}.
68c R type..namedata.*interface {}.
74e R type.[1]interface {}
6ff R type.[]interface {}
69c R type.interface {}
U type.string
So the conclusion so far is:
When the declared package name is different from the package folder name, package declaration will be used as an alternate name of the package.
Equivalent to this, but implicitly :
import pkg2 "pkg1"
And btw, since the package declaration is not reflected in the compiled .a
file, I guess the golang compilation requires the presence of .go
file.
go files in the same package AKA folder must have the same package name. The only exception are tests that can have a _test extension. The rule is 1 folder , 1 package therefore the same package name for all go files in the same folder.
The answer is yes , move the "hello" package files to their own folder or , use the same package name for all files in the same directory.