日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Go語言包和包管理詳解_Golang

作者:ourlang ? 更新時間: 2022-10-28 編程語言

1 包簡介

1.1 工作空間

go語言的工作空間必須由 bin、pkg、src三個目錄組成,可以在GOPATH環境變量中添加多個工作空間,但不能和GOROOT相同。通常go get使用第一個工作空間保存下載的第三方庫

workspace
	|
	+--- bin // go install 安裝目錄。
	|	  |
	| 	  +--- learn
	|
	|
	+--- pkg // go build ?成靜態庫 (.a) 存放目錄。
	| 	  |
	|	  +--- darwin_amd64
	| 			|
	| 			+--- mylib.a
	| 					|
	| 					+--- mylib
	|						 |
	|						 +--- sublib.a
	|
	+--- src // 項目源碼目錄。
		  |
		  +--- learn
		  | 	 |
		  | 	 +--- main.go
		  |
		  |
		  +--- mylib
				 |
				 +--- mylib.go
				 |
				 +--- sublib
						|
						+--- sublib.g

1.2 源文件

  • 編碼:源碼?件必須是 UTF-8 格式,否則會導致編譯器出錯。
  • 結束:語句以 “;” 結束,多數時候可以省略。
  • 注釋:?持 “//”、 “/**/” 兩種注釋?式,不能嵌套。
  • 命名:采? camelCasing ?格,不建議使?下劃線。

1.3 包命名

::: tip 包命名慣例

  • 給包命名的慣例是使用包所在目錄的名字。這讓用戶在導入包的時候,就能清晰地知道包名。
  • 盡量使用簡介明了的名字,但要避免沖突
  • 包名一般使用單數的形式,但是避免沖突的用的復數比如bytes,errors,strings等
  • 要避免包名有其他含義。比如 temp這種
  • 命名時考慮包名和成員如何配合,盡量減少包名和成員有重復 :::

1.4 main 包

  • 所有用 Go 語言編譯的可執行程序都必須有一個名叫 main 的包。 go語言的編譯器會將這種名字的包編譯為二進制可執行文件。
  • main包下肯定會有名為main()的函數,main()是程序的入口。
  • 編譯完會使用聲明 main 包的代碼所在的目錄的目錄名作為二進制可執行文件的文件名

2導包

關鍵字 Import ,進行導包。未使用的導入包,會編譯錯誤。

2.1 兩種方式

import a import b,…多次導入,以及import(a b c) 批量導入,如果導入的包不使用會報錯。

import "fmt"
//或者
import(
	"fmt"
    "time"
)

2.2 包的別名

import(
	io "fmt"
)
io.Println("hello world") //別名可以直接用,在包重名時很有用

2.3 簡潔模式

import (
	. "fmt"  //但是為了別人好看,一般還是不用這種
)
func main(){
	Println("hello")
}

2.4非導入模式(匿名導入)

即導入一個包并不使用它。如果不加_,就會出現編譯錯誤。 在這里用下劃線 _ 重命名導入的包。只導入,不使用。 但是這個包它進行了初始化,一般在init函數調用,這樣做的好處是,有些包我們不顯示使用它,但是有可能用到它,或者由用戶選擇使用哪個。比如 對特定圖像驅動包的初始化,在我們格式化轉換圖片用到。還有 database/sql包,可以先都初始化,讓用戶選擇不同的數據庫驅動。

import _ "test"     //非導入模式:僅讓該包執行初始化函數

2.5 導包的路徑

一般情況下是包的相對路徑。比如import "learn/test",標準庫中的包會在安裝 Go 的位置找到,即GOROOT。 Go 開發者創建的包會在 GOPATH 環境變量指定的目錄里查找。GOPATH 指定的這些目錄就是開發者的個人工作空間。

2.6 遠程導入

目前的大勢所趨是,使用分布式版本控制系統(Distributed Version Control Systems, DVCS) 來分享代碼,如 GitHub、 Launchpad 還有 Bitbucket。 Go 語言的工具鏈本身就支持從這些網站及 類似網站獲取源代碼。 Go 工具鏈會使用導入路徑確定需要獲取的代碼在網絡的什么地方。

比如:import "github.com/xxxx/xxx",用導入路徑編譯程序時, go build 命令會使用 GOPATH的設置,在磁盤上搜索這個包。事實上, 這個導入路徑代表一個URL,指向 GitHub上的代碼庫。如果路徑包含 URL,可以使用 Go 工具鏈從 DVCS 獲取包,并把包的源代碼保存在GOPATH指向的路徑里與 URL 匹配的目錄里。這個獲取過程 使用 go get 命令完成。

go get 將獲取任意指定的 URL 的包,或者一個已經導入的包所依賴的其 他包。由于 go get的這種遞歸特性,這個命令會掃描某個包的源碼樹,獲取能找到的所有依賴包。

3 初始化 init

每個包可以包含任意多個 init 函數,這些函數都會在程序執行開始的時候被調用。所有被編譯器發現的 init 函數都會安排在 main 函數之前執行。 init 函數用在設置包、初始化變量或者其他要在程序運行前優先完成的引導工作。舉例如下

 package postgres
 import (
	 "database/sql"
 )
 func init() { //初始化函數
     //這里省略。。
	 sql.Register("postgres", new(PostgresDriver))
 }

3.1 init總結

  • 每個源?件都可以定義?個或多個初始化函數。
  • 編譯器不保證多個初始化函數執行次序。
  • 初始化函數在單?線程被調用,僅執行?次。
  • 初始化函數在包所有全局變量初始化后執行。
  • 在所有初始化函數結束后才執行 main.main。
  • 無法調用初始化函數。

4 包管理

4.1 演變過程

  • 2013年:Gedep,社區第一個包管理工具
  • 2015年:vendor,Golang官方(golang1.5)
  • 2016、2017 年:dep、manul、Godep、Govendor、godm (Govendor勝出)
  • go module是Go1.11版本之后官方推出的版本管理工具,并且從Go1.13版本開始,go module將是Go語言默認的依賴管理工具。

4.2 Go Model優點

  • 不必須將項目目錄放在GOPATH中
  • 不使用vendor目錄,而是統一安裝到$GOPATH/pkg/mod/cache
  • build/run時,自動析出項目import的包并安裝

4.3 啟用go module

要啟用go module支持首先要設置環境變量GO111MODULE,通過它可以開啟或關閉模塊支持,它有三個可選值:off、on、auto,默認值是auto。 設置GO111MODULE=on之后就可以使用go module了,以后就沒有必要在GOPATH中創建項目了,并且還能夠很好的管理項目依賴的第三方包信息。 使用 go module 管理依賴后會在項目根目錄下生成兩個文件go.modgo.sum

  • GO111MODULE=off禁用模塊支持,編譯時會從GOPATHvendor文件夾中查找包。
  • GO111MODULE=on啟用模塊支持,編譯時會忽略GOPATHvendor文件夾,只根據 go.mod下載依賴。
  • GO111MODULE=auto,當項目在$GOPATH/src外且項目根目錄有go.mod文件時,開啟模塊支持。

4.4 GOPROXY

Go1.13之后GOPROXY默認值為proxy.golang.org,在國內是無法訪問的,所以十分建議大家設置GOPROXY

5 go mod詳解

5.1 go mod命令

常用的go mod命令如下:

go mod命令 描述
go mod download 下載依賴的module到本地cache(默認為$GOPATH/pkg/mod目錄)
go mod edit 編輯go.mod文件
go mod graph 打印模塊依賴圖
go mod init 初始化當前文件夾, 創建go.mod文件
go mod tidy 增加缺少的module,刪除無用的module
go mod vendor 將依賴復制到vendor下
go mod verify 校驗依賴
go mod why 解釋為什么需要依賴

5.2 go.mod說明

go.mod文件記錄了項目所有的依賴信息,其結構大致如下:

module github.com/ourlang/studygo/myblog
go 1.13
require (
	github.com/DeanThompson/ginpprof v0.0.0-20190408063150-3be636683586
	github.com/gin-gonic/gin v1.4.0
	github.com/go-sql-driver/mysql v1.4.1
	github.com/jmoiron/sqlx v1.2.0
	github.com/satori/go.uuid v1.2.0
	google.golang.org/appengine v1.6.1 // indirect
)
  • module用來定義包名
  • require用來定義依賴包及版本
  • indirect表示間接引用

5.2.1 依賴的版本

go mod支持語義化版本號,比如go get foo@v1.2.3,也可以跟git的分支或tag,比如go get foo@master,當然也可以跟git提交哈希,比如go get foo@e3702bed2。關于依賴的版本支持以下幾種格式:

gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7
gopkg.in/vmihailenco/msgpack.v2 v2.9.1
gopkg.in/yaml.v2 <=v2.2.1
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e
latest

5.2.2 replace

在國內訪問golang.org/x的各個包都需要翻墻,你可以在go.mod中使用replace替換成github上對應的庫。

replace (
	golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac => github.com/golang/crypto v0.0.0-20180820150726-614d502a4dac
	golang.org/x/net v0.0.0-20180821023952-922f4815f713 => github.com/golang/net v0.0.0-20180826012351-8a410e7b638d
	golang.org/x/text v0.3.0 => github.com/golang/text v0.3.0
)

5.3 go get

::: tip 在項目中執行go get命令可以下載依賴包,并且還可以指定下載的版本。

  • 運行go get -u將會升級到最新的次要版本或者修訂版本(x.y.z, z是修訂版本號, y是次要版本號)
  • 運行go get -u=patch將會升級到最新的修訂版本
  • 運行go get package@version將會升級到指定的版本號version
  • 如果下載所有依賴可以使用go mod download命令。 :::

5.3.1 整理依賴

我們在代碼中刪除依賴代碼后,相關的依賴庫并不會在go.mod文件中自動移除。這種情況下我們可以使用go mod tidy命令更新go.mod中的依賴關系

5.4 go mod edit

5.4.1 格式化

因為我們可以手動修改go.mod文件,所以有些時候需要格式化該文件。Go提供了一下命令:

go mod edit -fmt

5.4.2 添加依賴項

go mod edit -require=golang.org/x/text

5.4.3 移除依賴項

如果只是想修改go.mod文件中的內容,那么可以運行go mod edit -droprequire=package path,比如要在go.mod中移除golang.org/x/text包,可以使用如下命令

go mod edit -droprequire=golang.org/x/text

6 項目中使用go module

6.1 現有項目

如果需要對一個已經存在的項目啟用go module,可以按照以下步驟操作:

  • 在項目目錄下執行go mod init,生成一個go.mod文件。
  • 執行go get,查找并記錄當前項目的依賴,同時生成一個go.sum記錄每個依賴庫的版本和哈希值

6.2 新項目

對于一個新創建的項目,我們可以在項目文件夾下按照以下步驟操作:

  • 執行go mod init 項目名命令,在當前項目文件夾下創建一個go.mod文件。
  • 手動編輯go.mod中的require依賴項或執行go get自動發現、維護依賴。

原文鏈接:https://juejin.cn/post/7027497882081034276

欄目分類
最近更新