GOPATH"/home/wohu/GoCode"
1. 同一个包内的函数可以相互调用

代码结构如下:

wohu@wohu:~/GoCode/src$ tree temp
temp
├── chapter
│   ├── demo1
│   │   ├── demo1.go
│   │   └── demo1_lib.go
demo1.go
package main

func main() {
	name := "wohu"
	hello(name) // 调用以小写字母开头的同一个包内的函数
}

demo1_lib.go
package main

import "fmt"

// hello() 函数名称为小写开头
func hello(name string) {
	fmt.Printf("Hello, %s!\n", name)
}

运行结果:

[Running] cd "/home/wohu/GoCode/src/temp/chapter/demo1/" && go run .
Hello, wohu!

可以看到包内的函数是可以被包内其它任意函数调用的。

2. 包名和实际路径最后一个目录一致

代码目录结构如下:

wohu@wohu:~/GoCode/src$ tree temp
temp
├── chapter
│   ├── demo2
│   │   ├── demo2.go
│   │   └── lib
│   │       └── demo2_lib.go
demo2.go
package main

import (
	"temp/chapter/demo2/lib"     
)

func main() {
	name := "wohu"
	lib.Hello(name) // 直接使用 包名.函数名称来调用函数
}
demo2_lib.goGOPATH"temp/chapter/demo2/lib"
demo2_lib.go
package lib // 包名和实际路径中最后一个文件夹名称相同

import "fmt"

func Hello(name string) {
	fmt.Printf("Hello, %s!\n", name)
}

运行结果:

[Running] cd "/home/wohu/GoCode/src/temp/chapter/demo2/" && go run .
Hello, wohu!
3. 包名和实际路径最后一个目录不一致

同样的目录结构

wohu@wohu:~/GoCode/src$ tree temp
temp
├── chapter
│   ├── demo2
│   │   ├── demo2.go
│   │   └── lib
│   │       └── demo2_lib.go
demo2_lib.golib2
package lib2

import "fmt"

func Hello(name string) {
   fmt.Printf("Hello, %s!\n", name)
}

demo2.go
package main

import (
	"temp/chapter/demo2/lib"
)

func main() {
	name := "wohu"
	lib.Hello(name)
}

运行出错:

[Running] cd "/home/wohu/GoCode/src/temp/chapter/demo2/" && go run .
# temp/chapter/demo2
./demo2.go:4:2: imported and not used: "temp/chapter/demo2/lib" as lib2
./demo2.go:9:2: undefined: lib

为什么会是这样?根本原因就是,我们在源码文件中声明所属的代码包与其所在目录的名称不同。

srclib
import

而如下修改,

package main

import (
	"temp/chapter/demo2/lib2"
)

func main() {
	name := "wohu"
	lib2.Hello(name)
}

运行报错:

[Running] cd "/home/wohu/GoCode/src/temp/chapter/demo2/" && go run .
demo2.go:4:2: cannot find package "temp/chapter/demo2/lib2" in any of:
	/usr/local/go/src/temp/chapter/demo2/lib2 (from $GOROOT)
	/home/wohu/GoCode/src/temp/chapter/demo2/lib2 (from $GOPATH)

"temp/chapter/demo2/lib2"

继续使用别名修改

package main

import (
	p "temp/chapter/demo2/lib"
)

func main() {
	name := "wohu"
	p.Hello(name)
}

或者

package main

import (
	"temp/chapter/demo2/lib"
)

func main() {
	name := "wohu"
	lib2.Hello(name)
}
importlib2.Hello(name)
import "目录名"
包名.Hello()

因此,为了不让该代码包的使用者产生困惑,我们总是应该让声明的包名与其父目录的名称一致。

包名和目录名不一致时需要注意:

  • 目录名使用在文件层面,例如库的安装路径名、库文件名以及被导入时的路径;
  • 包名使用在代码层面,例如调用包的函数时;