Go语言进阶,详解自定义模块的调用(同级目录与不同级目录)

        Go语言中的模块是让一些相同业务的功能集合在一个目录,方便被其他业务调用,独立性强,耦合低,方便维护。Go语言零基础入门,从安装到运行代码 在这篇文章也有示例,但只说了一种生成go.mod的方式来调用的方法,尤其对于同级目录的go文件的调用,有坑在里面。

先查看下自己的go的环境,命令行输入: go env

如果列表中发现是关闭的

 set GO111MODULE=off

我们将其打开:

go env -w GO111MODULE=on

其余的环境变量,大家都可以去了解,最关键的是安装目录GOROOT与工作目录GOPATH

GO111MODULE开启

准备工作:新建一个工作目录mywork,在下面新建两个目录,testa和testb目录,再分别在其下面新建两个go文件:testa.go和testb.go,现在的目的是testa调用testb中的函数,以下是cmd命令行操作:

REM:进入目录testb,生成一个模块文件go.mod,使用域名是为了让模块名称唯一:tony.com/testb,虽然可以使用别名,但不是一种良好的编码规范

cd testb
go mod init tony.com/testb
REM:进入目录testa,生成一个模块文件go.mod,模块名称指向其所在位置,最后使用tidy整理模块即可

cd testa
go mod init tony.com/testa
go mod edit -replace tony.com/testb=../testb
go mod tidy

调用的时候,就是导入上面生成的模块名:import "tony.com/testb",然后使用testb调用里面的函数即可

C:\Users\Tony\go\src\mywork\testa>go run testa.go
/*
和的结果: 7
你好,寅恪光潜,近来可好?
*/

testa.go

package main

import (
	"fmt"
	"tony.com/testb"
)

func main() {
	fmt.Println("和的结果:", testb.Sum(3, 4))
	fmt.Println(testb.Hello("寅恪光潜"))
}

testb.go

package testb

import "fmt"

func Sum(i1 int, i2 int) int {
	return i1 + i2
}

func Hello(s string) string {
	res := fmt.Sprintf("你好,%s,近来可好?", s)
	return res
}

GO111MODULE关闭

如果是开启的,我们将它设置成关闭模块模式,运行看下效果go run testa.go

go env -w GO111MODULE=off

testa.go:6:2: cannot find package "tony.com/testb" in any of:
        D:\Program Files\Go\src\tony.com\testb (from $GOROOT)
        C:\Users\Tony\go\src\tony.com\testb (from $GOPATH)

错误提示:我们发现找不到包了,在安装目录与工作目录都没有找到。
这个是肯定的,因为不是go.mo模块模式了,而是会在去寻找实际的本地目录,所以我们将这个模块的名称修改成本地目录即可,根目录是mywork,因为是存放在GOPATH的src目录下面

import "mywork/testb"
C:\Users\Tony\go\src\mywork\testa>go run testa.go
/*
和的结果: 7
你好,寅恪光潜,近来可好?
当然前提条件是需要放在工作目录的src里面
*/

同级目录的go文件调用

那如果同一目录下面的go文件怎么去调用呢。比如在testa目录新建一个testaa.go文件,然后调用这个新建文件里面的函数:

testaa.go

//package testaa
package main

func Sub(i1 int, i2 int) int {
	return i1 - i2
}

我们来调用试下:

package main
import "mywork/testa/testaa"
func main() {
	fmt.Println(testaa.Sub(5, 2))
}

C:\Users\Tony\go\src\mywork\testa>go r           un testa.go
testa.go:7:2: cannot find package "mywork/testa/testaa" in any of:
        D:\Program Files\Go\src\mywork\testa\testaa (from $GOROOT)
        C:\Users\Tony\go\src\mywork\testa\testaa (from $GOPATH)

我们发现找不到这个testaa包名,但实际上在这个目录下面是有这样的包名存在的啊。为什么?

首先这个testaa包名是一个目录,这里不是目录,是文件,另外就是同级目录不需要加载模块,只需要编译即可,然后调用的时候也是直接使用方法名调用,这是关键点,因为上面go run testa.go,没有编译testaa.go文件,所以出现找不到包或者是方法未定义等其他错误。
我们来到testa目录,然后编译里面的文件,这样就可以直接调用了,如下:

C:\Users\Tony\go\src\mywork\testa>go build

这样就在当前目录下面编译成了一个testa.exe文件,我们运行看下:

C:\Users\Tony\go\src\mywork\testa>testa
/*
和的结果: 7
你好,寅恪光潜,近来可好?
3
*/

源码如下,其中调用的时候直接Sub不需要前面加包名来引用

package main

import (
	"fmt"
	"mywork/testb"
)

func main() {
	fmt.Println("和的结果:", testb.Sum(3, 4))
	fmt.Println(testb.Hello("寅恪光潜"))
	fmt.Println(Sub(5, 2))
}

巩固习题

根据上面的方法,现在我们在testb里面新增一个testbb.go文件,然后testb去调用testbb,最后在testa中调用他们,会处理吗?

testb.go

package testb

import "fmt"

func Sum(i1 int, i2 int) int {
	return i1 + i2
}

func Hello(s string) string {
	res := fmt.Sprintf("你好,%s,近来可好?", s)
	res1 := HelloBB("法外狂徒张三")
	return res + res1
}

testbb.go

package testb

import "fmt"

func HelloBB(s string) string {
	res := fmt.Sprintf("Hello %s", s)
	return res
}

细心的伙伴们可能发现,同级目录的包名package要一样,不然编译会出错,比如testb下面所有的go文件的统一包名为package testb,然后我们将testb下面所有文件的编译,再编译testa所有文件,最后就会生成一个testa.exe,从这里也可以得出,后期同级目录下面的go文件的package名称统一是目录名称即可。

C:\Users\Tony\go\src\mywork\testb>go build

C:\Users\Tony\go\src\mywork\testb>cd ../testa

C:\Users\Tony\go\src\mywork\testa>go build

C:\Users\Tony\go\src\mywork\testa>testa

/*
和的结果: 7
你好,寅恪光潜,近来可好?Hello 法外狂徒张三
3
*/
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

寅恪光潜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值