Go 语言同一个包内函数调用、包名和实际路径最后一个目录不一致问题

以下代码的 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()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wohu007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值