Go 分布式学习利器(16) -- go中可复用的package构建
通過本文,你將了解go 語言中如何將自己的package構建到項目中 以及如何將遠程(github)的package構建到項目中。
1. 構建本地的package
- package 是可復用模塊的基本單元,以首字母大寫的函數實現來表明可被包外代碼訪問
- 代碼的package可以和所在路徑的代碼不一致
- 同一目錄里的Go 代碼的package 要保持一致
個人理解 本地包就像是C++/C中的頭文件,其他代碼只需要包含該頭文件,即可使用頭文件中生命的函數。
這里構建自己Go語言的package的時候需要注意代碼路徑,在環境中指定好的GOPATH路徑中的src目錄下創建自己實現的package目錄。
比如指定~/.bashrc中:
export GOPATH="~/go/"
那么在該路徑下的src目錄創建自己的package目錄即可,如下 series目錄
實現series.go,同時在其他的package目錄下的源碼文件中import "ch11/series"即可使用series.go中實現的函數
ps :
series.go中實現的函數名字開頭需大寫,這樣是指定當前函數能夠被在包外調用
其中series.go實現代碼如下:
package seriesimport "fmt"// 獲取斐波那契數列,函數名必須大寫,如果小寫則在后面的包外調用中會報語法錯
func GetFibList(n int) []int{if n < 2 {return nil}if n > 100 {return nil}fibList := []int{1,1}for i := 2; i < n; i++ {fibList = append(fibList, fibList[i-1] + fibList[i-2])}return fibList
}
在ch11目錄下的package_test目錄創建一個package_test.go測試代碼,調用series包中的函數
package package_testimport (fib "test/ch11/series" // 我的src目錄下 是test/ch11/series"testing"
)func TestPackage(t *testing.T) {t.Log(fib.GetFibList(5))
}
最后成功運行,輸出如下:
=== RUN TestPackagepackage_test.go:9: [1 1 2 3 5]
--- PASS: TestPackage (0.00s)
2. 包內 初始化 init方法
GO支持初始化包的方法,且該方法有如下幾個比較意思的特性
- 在main被執行前,所有依賴的package的init方法都會被執行
- 不同包的init函數按照包導入的依賴關系決定執行順序
比如pkg1 和 pkg2兩個包,第一個包被先import的,那么pkg1的init函數會先執行 - 每個包可以有多個init函數
- 包的每個源文件也可以有多個init函數
比如之前的series包中,我們在series.go中加入兩個init函數
package seriesimport "fmt"func init() {fmt.Println("first init")
}func init() {fmt.Println("second init")
}func GetFibList(n int) []int{ /* 兩個返回值 */if n < 2 {return nil}if n > 100 {return nil}fibList := []int{1,1}for i := 2; i < n; i++ {fibList = append(fibList, fibList[i-1] + fibList[i-2])}return fibList
}
多個init在test文件中執行的時候會被先執行:
package package_testimport ("testing"fib "test/ch11/series"
)func TestPackage(t *testing.T) {t.Log(fib.GetFibList(5))
}
輸出如下,可以看到series中的方法被調用時,init函數會優先其他所有調用者執行
first init
second init
=== RUN TestPackagepackage_test.go:9: [1 1 2 3 5]
--- PASS: TestPackage (0.00s)
PASS
init函數有助于我們提前初始化好自己包內的一些資源
3. 構建遠端的package
很多時候我們項目中需要一些開源的go框架:分布式協調服務etcd, 分布式通信go-grpc等,需要使用這一些開源代碼中的package包,那么go語言提供了方便的獲取方式,類似如下:
go get -u github.com/easierway/concurrent_map
指定的github的源碼路徑不需要加.git,以上命令會將http://github.com/easierway/concurrent_map.git中的master分支代碼放入到GOPATH的src/github.com 路徑下,并且不包含項目中的.git目錄(不會隨著社區更新)。
包含之后就可以直接使用該遠程package了:
package remote_packageimport "testing"
import cm "github.com/easierway/concurrent_map" //導入遠端下載下來的packagefunc TestConcurrentMap(t *testing.T) {m := cm.CreateConcurrentMap(99) // 調用包內的相關方法m.Set(cm.StrKey("key"),10)t.Log(m.Get(cm.StrKey("key")))
}
輸出如下:
=== RUN TestConcurrentMapremote_package_test.go:9: 10 true
--- PASS: TestConcurrentMap (0.00s)
PASS
總結
以上是生活随笔為你收集整理的Go 分布式学习利器(16) -- go中可复用的package构建的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 知者利仁下一句是什么呢?
- 下一篇: Zookeeper ZAB协议原理浅析