• 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命令行操作:

    1. REM:进入目录testb,生成一个模块文件go.mod,使用域名是为了让模块名称唯一:tony.com/testb,虽然可以使用别名,但不是一种良好的编码规范
    2. cd testb
    3. go mod init tony.com/testb
    1. REM:进入目录testa,生成一个模块文件go.mod,模块名称指向其所在位置,最后使用tidy整理模块即可
    2. cd testa
    3. go mod init tony.com/testa
    4. go mod edit -replace tony.com/testb=../testb
    5. go mod tidy

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

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

    testa.go

    1. package main
    2. import (
    3. "fmt"
    4. "tony.com/testb"
    5. )
    6. func main() {
    7. fmt.Println("和的结果:", testb.Sum(3, 4))
    8. fmt.Println(testb.Hello("寅恪光潜"))
    9. }

    testb.go

    1. package testb
    2. import "fmt"
    3. func Sum(i1 int, i2 int) int {
    4. return i1 + i2
    5. }
    6. func Hello(s string) string {
    7. res := fmt.Sprintf("你好,%s,近来可好?", s)
    8. return res
    9. }

    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"
    1. C:\Users\Tony\go\src\mywork\testa>go run testa.go
    2. /*
    3. 和的结果: 7
    4. 你好,寅恪光潜,近来可好?
    5. 当然前提条件是需要放在工作目录的src里面
    6. */

    同级目录的go文件调用

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

    testaa.go

    1. //package testaa
    2. package main
    3. func Sub(i1 int, i2 int) int {
    4. return i1 - i2
    5. }

    我们来调用试下:

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

    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文件,我们运行看下:

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

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

    1. package main
    2. import (
    3. "fmt"
    4. "mywork/testb"
    5. )
    6. func main() {
    7. fmt.Println("和的结果:", testb.Sum(3, 4))
    8. fmt.Println(testb.Hello("寅恪光潜"))
    9. fmt.Println(Sub(5, 2))
    10. }

    巩固习题

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

    testb.go

    1. package testb
    2. import "fmt"
    3. func Sum(i1 int, i2 int) int {
    4. return i1 + i2
    5. }
    6. func Hello(s string) string {
    7. res := fmt.Sprintf("你好,%s,近来可好?", s)
    8. res1 := HelloBB("法外狂徒张三")
    9. return res + res1
    10. }

    testbb.go

    1. package testb
    2. import "fmt"
    3. func HelloBB(s string) string {
    4. res := fmt.Sprintf("Hello %s", s)
    5. return res
    6. }

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

    1. C:\Users\Tony\go\src\mywork\testb>go build
    2. C:\Users\Tony\go\src\mywork\testb>cd ../testa
    3. C:\Users\Tony\go\src\mywork\testa>go build
    4. C:\Users\Tony\go\src\mywork\testa>testa
    5. /*
    6. 和的结果: 7
    7. 你好,寅恪光潜,近来可好?Hello 法外狂徒张三
    8. 3
    9. */
  • 相关阅读:
    深度学习论文: MobileNetV4 - Universal Models for the Mobile Ecosystem及其PyTorch实现
    C++刷题测试样例输入输出
    【优化模型】报童的诀窍
    java项目之抗疫医疗用品销售平台ssm+jsp
    copilot 产生 python工具函数并生成单元测试
    【从零开始学微服务】07.微服务常用的开发框架
    前端:nodejs多版本管理工具nvm
    web技术分享| 【高德地图】实现自定义的轨迹回放
    二叉搜索树的最近公共祖先
    CSS布局概念与技术教程
  • 原文地址:https://blog.csdn.net/weixin_41896770/article/details/127804435