Go中的Package和Module分析

Package

  • 所謂package(包)其實就是代碼的一種組織管理方式,代碼多了就須要放入文件,文件多了就須要歸類放入文件夾,就比如咱們在給電腦裝軟件時會進行歸類安裝,其實也是有意無心對電腦軟件安裝的一種管理方式。那麼不一樣的go文件交給不一樣的package管理時,若是A package須要引用 B package中的文件時go是怎麼處理的?基於此,咱們來對go的package和module一探究竟java

  • 咱們以一個例子來學習,這裏假設咱們作一個學生管理系統,以下代碼git

//學生管理系統(學生管理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中文件夾名稱和包名稱是能夠不同的;須要使用其它包中的方法時,引入包所在的路徑,真實使用時,是經過包名.的形式去使用,github

  • 舉個例子golang

  • 假設文件夾名稱爲:student_manage,
  • 包名爲:student
  • 那麼在main中使用時,應該import student_manage ,但真實調用其方法時應該是student.QueryStudent("stuNo"),在真實項目中,go官方建議文件夾名稱和包的名稱同樣,以防止歧義產生,同時儘可能簡短。redis

  • 理解了package,那麼go是如何尋找包路徑的,看下面代碼chrome

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: 存儲咱們包的路路徑
  • pkg:是存儲go install的歸檔文件
  • bin: 存儲go的可執行文件微信

  • 舉個例子以下:maven

  • 假設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中這一切是怎麼作的呢?ide

  • 在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那點事」,更多精彩期待你的到來

相關文章
相關標籤/搜索