两种方式愉快的使用go.mod引用自己开发的package包(库)

GO引用自己写的模块方式1 ——仅使用“根”路径的go.mod
在go中开启了GO111MODULE=on 就可以使用go语言自带的mod来管理自己开发的项目的依赖,从而可以摆脱传统的必须把依赖的模块放在GOROOT或者GOPATH下的src,pkg等目录下的方式。

当我们自己开发了一个公共的模块,并且想要在其他的项目中使用它,那么我们在项目的顶层文件夹的“根路径“下使用如下命令:

go mod init chatroom
go mod tidy
其中 chatroom是自定义的项目名称。

如下的项目,有一个公共的message模块,想要在client和server两个单独的路径下的go程序文件中引用它,

那么我们需要在message这个模块的外层执行上面提到的两个命令。这样做就是把client,server,message视为一整个的大package,用一个go.mod来管理。

 整体文件结构如下:

CHATROOM

│  go.mod

├─client

│  │  client.exe

│  │  main.go

│  │

│  └─login

│          login.go

├─message

│      message.go

└─server

        main.go

        server.exe

而在具体引用message包时,如在client下的login的分包pacakge中,引用message模块:

client/login/login.go 引用 message:

其中引用的时候开头的前缀chatroom是因为在项目ChatRoom文件夹的路径下,使用go mod init命令时把当前CharRoom作为根路径,go.mod自定义chatroom为整个大项目的模块名称,通过查看CharRoom/go.mod可以看到:

 也就是说在整个项目的根路径下使用go mod init初始化mod时指定的什么mod名称,那么在引用的时候,import的书写形式就以项目根路径初始化的mod名称开头,然后再按照要引入的模块相对于根路径go.mod的路径进行导入。

比如这里message模块相对于根路径go.mod的路径就是 go.mod/message ,所以在项目的其他xxx.go文件中,要引用message时,导入import的语句就是”chatroom/message”.

而在使用了顶层根路径下的go.mod这种方式管理之后,如果自己的项目结构中有自己单独的内部分包package需要导入——如client下有一个client自己内部的名为login的分包package,要在client下的main.go文件中引用它:

那么在client项目下,client/main.go文件中,import时候的形式就如下:

也是从顶层根路径的mod名称开始,按照要引用的package的相对根路径进行import.

因为login这个package相对于顶层根路径下的go.mod的路径为 go.mod/client/login,所以其在clinet/main.go导入形式就是 “chatroom/client/login”.

 容易犯的错误:

如果使用一个顶层go.mod管理这个大项目时,不要在各个子项目下在初始化各个子项目或者是分包的go.mod
如下:

如果除了在顶层文件夹路径下的go.mod之外,在子项目client下使用go mod init client把client又添加go.mod进行定义,此时原来的go文件中的引用形式将不可用:

即使修改import导入路径,从client的go.mod开始,虽然没有提示错误但是,编译报错:

这样又回归到了最原始的GOROOT和AOPATRH下src的用法,也就是说只要不是处于GOROOT下的src中的package,那么当自己项目路径下的go.mod和要导入的自己开发的模块的go.mod同时存在的时候,就会存在问题。

解决办法有两个:

把自己开发的package模块挪到GOROOT下的src目录下去,作为golang全局公共模块,这种方式个人认为,如果不想把自己的模块共享出去就不推荐,因为这样自己开发的pcakge就全局公开了,也能被其他项目引用,如果只是自己项目内公开就不建议这样做;
或者是就只保持在项目的顶层路径下的唯一的一个go.mod即可,不在除顶层文件夹根路径之外的,其他子项目下再初始化任何的go.mod。如在本例中,只保持chatRoom下的唯一一个go.mod,在其余的client,server,message等模块路径下不初始化,也不添加任何自己子项目的mod,如果已经添加了的,删除client,server,message模块下的go.mod;
方式1总结:在引用自己开发的package时,把整个项目作为一个大的package用一个go.mod进行管理,开发的项目公共模块作为其中一个子包package来使用,在项目顶层文件夹路径下(根路径)进行go mod init的初始化,并且只保持这个根路径下的唯一go.mod即可,引用包时按照顶层go.mod中定义的名称为前缀,逐层添加对应要引用的package的路径即可。

GO引用自己写的模块方式2——定义各个子package的go.mod
严格来说,在go中没有所谓明确的”项目”这一概念,go中都是包package。

另外一种使用mod的方式是给各个包package都添加其自己的go.mod,然后供其他的包来使用,这种方式在使用上对于被引用的”公共模块”(或者说是库)添加其go.mod时,只需要使用go mod init xxx以及 go mod tidy命令初始化即可,但是在要主动引入的package中,在引入的时候,还需要对其go.mod进行编辑,如下:

如下图,在这个chatroom结构下,message是一个需要被client和server都引用的模块,它的初始化就简单使用如下命令初始化其go.mod即可:

go mod init message
go mod tidy


 但是对于要主动引入的server和client这两个package来说,其go.mod的内容除了要用go mod init xxx和go mod tidy之外还需要手动编辑go.mod,添加requier信息和replace信息步骤如下:

添加require信息时添加要引用的模块名和其版本号即可,版本号可自定义;
添加replace信息是为了指明要引用的模块相对当前模块go.mod的路径,以便能够找到要引用的模块,如当前message相对于server路径是../message,所以server要引用messge时,在server下的go.mod中,replace信息中添加的就是 replace message=>../message,当然也可使用绝对路径;
如下是client,Server要引用公共的message模块时messge/Server/Client各个packege添加和编辑go.mod的步骤:
1.公共包messsage下的go.mod
go mod init message
go mod tidy
        除此之外,不需要任何的编辑动作

2.Server下的go.mod
go mod init server
go mod tidy
编辑server下的go.mod添加require和replace信息


在server模块的xxx.go文件中,引用message直接import模块名即可,这里不需要再添加前缀路径,直接import模块名即可,因为其已经在replace信息中写明了 replace message=>../message:

3.Client下的go.mod
go mod init client
go mod tidy
编辑client下的go.mod添加require和replace信息


同样在client中的xxx.go文件中,引用message也是直接import模块名即可:

这种情况下,如果是自己的子模块有自己的分包package,如 client这个模块除了引用公共的messga模块(库)之外,还有自己的login分包,那么因为此时client下有了自己的go.mod,所以其自己内部的login分包,就归属到client自己这个package下,当client要引用自己的分包login时,其引用形式就是先添加自己模块的mod名——client前缀(因为go mod init client 命令把client模块初始化名为client),然后跟上要引入的分包login在自己模块内的package(文件夹)路径(分包login相对于clinet的go.mod的路径):import “client/login”:

整体看下来文件结构如下,client,message,server各自都是一个由其本身go.mod管理的package:

CHATROOM

├─client

│  │  client.exe

│  │  go.mod

│  │  main.go

│  │

│  └─login

│          login.go

├─message

│      go.mod

│      message.go

└─server

        go.mod

        main.go

        server.exe

方式2总结:当项目要引用自定义的公共模块时,在各个模块中定义自己的go.mod,对于被引入的公共模块初始化其go.mod信息即可,对于主动要引入其他公共模块的模块而言,除了要go mod init自身的go.mod文件外,还需要编辑其go.mod文件,添加require信息写明要引用的模块名,以及添加replace信息指明要引用的公共模块相对于当前go.mod的相对或者绝对路径,然后import时直接import包名即可。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/wvxvsuizhong/article/details/131990052

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值