以下代码的 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.go
所在的相对 GOPATH
路径为 "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.go
代码, 声明其包名为 lib2
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
为什么会是这样?根本原因就是,我们在源码文件中声明所属的代码包与其所在目录的名称不同。
请记住,源码文件所在的目录相对于 src
目录的相对路径就是它的代码包导入路径,而实际使用其程序实体时给定的限定符(本示例代码中的 lib
)要与它声明所属的代码包名称对应。
重要: 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)
}
即在 import
时导入的是目录名,而在外部进行调用时需要使用包名作为前缀 lib2.Hello(name)
。
import "目录名"
包名.Hello()
因此,为了不让该代码包的使用者产生困惑,我们总是应该让声明的包名与其父目录的名称一致。
包名和目录名不一致时需要注意:
- 目录名使用在文件层面,例如库的安装路径名、库文件名以及被导入时的路径;
- 包名使用在代码层面,例如调用包的函数时;