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

SunPengWei · · 1656 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

### package > 所谓package(包)其实就是代码的一种组织管理方式,代码多了就需要放入文件,文件多了就需要归类,管理放入文件夹,就好比我们在给电脑装软 件时会进行归类安装其实也是有意无意对电脑软件安装的一种方式。 那么不同的go文件交给不同的package管理时,如果A package需要引用 B package中的文件时go是怎么处理的?基于此,我们来对go的package和module一探究竟 * 我们以一个例子来学习,这里假设我们做一个学生管理系统,如下代码 ``` go //学生管理系统(学生管理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是如何寻找包路径的 ```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/chromedp@v0.1.0" 修改指定的版本,修改之后执行第二步 ``` > 如何给一个项目打上版本号,这是通过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那点事”,更多精彩期待你的到来**

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1656 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传