40

【GoLang那点事】go的package和module分析

 4 years ago
source link: https://www.tuicool.com/articles/mURBny6
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

package

所谓package(包)其实就是代码的一种组织管理方式,代码多了就需要放入文件,文件多了就需要归类,管理放入文件夹,就好比我们在给电脑装软 件时会进行归类安装其实也是有意无意对电脑软件安装的一种方式。 那么不同的go文件交给不同的package管理时,如果A package需要引用 B package中的文件时go是怎么处理的?基于此,我们来对go的package和module一探究竟

  • 我们以一个例子来学习,这里假设我们做一个学生管理系统,如下代码
//学生管理系统(学生管理package,成绩管理package,主package)
student_manage_system
   student_manage
      student.go
   achievement_manage
      achievement.go
   main
      main.go

student.go文件内容如下
package student_manage
func QueryStudent(no string) Student{
   
}

main.go 文件内容如下
package main
import student_manage
func  main()  {
    student := sutdent_manage.QueryStudent("stuNo")
}

在main包需要依赖student_manage 包查询学生对象,在go中是通过import关键字导入我们需要使用的包的路径,什么是包,什么是包的路径?以student_manage文件夹 和  package后面写的student_manage 为例,乍一看,一模一样,没什么区别;其实不然,在go中文件夹名称和包名称是可以不一样的;需要使用其它包中的方法时,引入包所在的路径,真实使用时,是通过包名.的形式使用,

假设文件夹名称为student_manage,

包名为student

那么在main中使用时,应该import student_manage ,但真实调用其方法时应该是student.QueryStudent("stuNo"),在真实项目中,go官方建议文件夹名称和package名称一样,以防止歧义产生,同时尽量简短。

  • 理解了package,那么go是如何寻找包路径的
package main
import(
    "fmt"
    "student_manage"
)
func main(){
}

如上代码中,我们引入了fmt包,student_manage包,我们知道fmt是go sdk中的包,student_manage是我们自己的包,在go中,有两个变量:goroot,gopath

  • GOOOT

goroot指的是go的安装路径,比如 D:\sdk\go12;在这个目录下有一个src的文件夹 D:\sdk\go12\src,大家可以点进去看一下,在里面你会fmt

  • GOAPTH

gopath是go项目的路径,我们开发一个学生管理系统,通过gopath指定学生管理系统路径

gopath下有三个目录

src src就是存储我们包的路路径 pkg pkg是存储go install的归档文件 bin bin是存储go的可执行文件

  • 举个例子如下:

假设gopath指定路径D:\mygo,那么最终目录结构为

  D:\mygo\
        src
            student_manage_system(项目名称)
                student_manage
                    student.go
                main
                    mian.go
        pkg
            存储最后打包后的归档文件
        bin
            存储执行文件

module

举个例子,我们在使用别的包的时候需要引入,比如小明开发了一个消息中间件mq,我们在使用时如何引入小明的包,了解java的人知道 maven, java中包的管理,依赖,版本等是通过maven中央仓库引入,也就是你开发一个java程序可以打成jar包,上传maven中央仓库,那么别人使用是就可以通过mavnen坐标来引入你开发的jar,那么go中这一切是怎么做的呢?

在go1.11之后go官方推出了go module,在这之前go的包管理百花齐放(也意味着比较混乱),主流的有 govender,glide,gopm,以及半官方的 dep,这里对这些不做介绍,感兴趣的可以去google一下,我们主要学习一下go官方的module

刚才我们提到了java的maven中央仓库,谁开发了谁上传,谁想用谁下载,go也有这么一个中央仓库,就是大名鼎鼎的 github,我们还以学生管理系统为例,在说项目之前,再说一下gopath,在go1.11之后,gopath概念淡化了许多,不再是以前的结构,gopath的作用是存储项目依赖的包路径,项目本身可以创建在任何地方

go1.11之后gopath
默认gopath路径,当前系统账户目录下会有一个go目录,如下

C:/Users/sunpengwei/go
    pkg
        mod
整体目录是
C:/Users/sunpengwei/go/pkg/mod

go module具体如何使用呢?我们在github上新建一个学生管理系统,然后git clone到本地

student_manage_system
在根目录下执行 go mod init 会在项目目录下生成一个go.mod文件,
文件内容是module student_manage_system(module的名称)
go 1.12(go的版本)

有了go.mod 文件,假设我们需要引用一个redis第三方包 go.mod 中有两个关键字 reuqire  replace

  • require字段:  require github.com/gomodule/redigo v2.0.0+incompatible require 代表必须,必要的, github.com/gomodule/redigo 是包的路径 v2.0.0是版本 +incompatible暂且不讨论,这样我们就在项目中使用了redigo包,就可以使用redigo包中的方法了,在真实使用时我们只需要的是导入具体的包,如下代码示例
module student_manage_system
require github.com/gomodule/redigo v2.0.0+incompatible
go 1.12
package main
import(
   "github.com/gomodule/redigo/redis"
)
func main(){   
}
  • replace字段,从字面理解意思是替换

假设学生管理系统有两个包student_manage和achievement_manage,

现在achievement_manage包需要使用student_manage包中的方法怎么办?我们的项目托管给了github, 此时包路径为 github.com/sunpengwei1992/student_manage_system, 但这时我们能的代码并没有上传至github,这个时候replace字段就开始使用了,我们对包路径进行了替换 。 把github.com/sunpengwei1992/student_manage_system替换成 ./ 在本地使用时只需要通过 ./student_manage使用就可以了

replace github.com/sunpengwei1992/student_manage_system v1.0.0 => ./

go module 常用的一些命令

go mod init module_name 初始化mod文件
go mod tidy 下载依赖的包
go get github.com/jtianling/goModule@latest 的形式更新到最新版
go get -u 的形式升级所有的依赖库
go mod edit -require="github.com/chromedp/[email protected]" 修改指定的版本,修改之后执行第二步

如何给一个项目打上版本号,这是通过git的tag来做到的

git tag //查询所有的tag
git tag -a v1.0 -m "对Tag的描述信息"
git push origin --tags

大家可以看我github的代码测试 https://github.com/sunpengwei1992/go_module_test

欢迎大家关注微信公众号:“golang那点事”,更多精彩期待你的到来


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK