這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
1. 前言
在讀docker及distribution源碼的過程中遇到了很多坑,在此將這些坑記錄下來,隨時更新,在第二節中會給出更新的內容
2.包括的golang特性
- Godeps
- vendor
_
底線
- 介面查詢
- 包命名
- 結構體和介面
2.Godeps
- golang1.1版本之後,有了godep依賴管理工具,項目下新加了Godeps檔案夾,其中含有項目依賴的包,記錄包依賴的檔案為Godeps.json,下面是一個例子,該例子為distribution2.1項目的Godeps,在github.com/docker/distribution可以直接用github.com/spf13/cobra中的結構而不用匯入,可見
ImportPath
下的包可以直接調用Deps
下含有的包:
{ "ImportPath": "github.com/docker/distribution", "GoVersion": "go1.4.2", "Packages": [ "./..." ], "Deps": [ { "ImportPath": "github.com/AdRoll/goamz/aws", "Rev": "aa6e716d710a0c7941cb2075cfbb9661f16d21f1" }, { "ImportPath": "github.com/AdRoll/goamz/cloudfront", "Rev": "aa6e716d710a0c7941cb2075cfbb9661f16d21f1" }, { "ImportPath": "github.com/AdRoll/goamz/s3", "Rev": "aa6e716d710a0c7941cb2075cfbb9661f16d21f1" }, { "ImportPath": "github.com/Azure/azure-sdk-for-go/storage", "Rev": "97d9593768bbbbd316f9c055dfc5f780933cd7fc" }, { "ImportPath": "github.com/Sirupsen/logrus", "Comment": "v0.7.3", "Rev": "55eb11d21d2a31a3cc93838241d04800f52e823d" }, { "ImportPath": "github.com/bugsnag/bugsnag-go", "Comment": "v1.0.2-5-gb1d1530", "Rev": "b1d153021fcd90ca3f080db36bec96dc690fb274" }, { "ImportPath": "github.com/bugsnag/osext", "Rev": "0dd3f918b21bec95ace9dc86c7e70266cfc5c702" }, { "ImportPath": "github.com/bugsnag/panicwrap", "Rev": "e5f9854865b9778a45169fc249e99e338d4d6f27" }, { "ImportPath": "github.com/denverdino/aliyungo/oss", "Rev": "0e0f322d0a54b994dea9d32541050d177edf6aa3" }, { "ImportPath": "github.com/denverdino/aliyungo/util", "Rev": "0e0f322d0a54b994dea9d32541050d177edf6aa3" }, { "ImportPath": "github.com/docker/docker/pkg/tarsum", "Comment": "v1.4.1-3932-gb63ec6e", "Rev": "b63ec6e4b1f6f5c77a6a74a52fcea9564538c575" }, { "ImportPath": "github.com/docker/libtrust", "Rev": "fa567046d9b14f6aa788882a950d69651d230b21" }, { "ImportPath": "github.com/garyburd/redigo/internal", "Rev": "535138d7bcd717d6531c701ef5933d98b1866257" }, { "ImportPath": "github.com/garyburd/redigo/redis", "Rev": "535138d7bcd717d6531c701ef5933d98b1866257" }, { "ImportPath": "github.com/gorilla/context", "Rev": "14f550f51af52180c2eefed15e5fd18d63c0a64a" }, { "ImportPath": "github.com/gorilla/handlers", "Rev": "60c7bfde3e33c201519a200a4507a158cc03a17b" }, { "ImportPath": "github.com/gorilla/mux", "Rev": "e444e69cbd2e2e3e0749a2f3c717cec491552bbf" }, { "ImportPath": "github.com/inconshreveable/mousetrap", "Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" }, { "ImportPath": "github.com/mitchellh/mapstructure", "Rev": "482a9fd5fa83e8c4e7817413b80f3eb8feec03ef" }, { "ImportPath": "github.com/ncw/swift", "Rev": "ca8cbbde50d4e12dd8ad70b1bd66589ae98efc5c" }, { "ImportPath": "github.com/noahdesu/go-ceph/rados", "Comment": "v.0.3.0-29-gb15639c", "Rev": "b15639c44c05368348355229070361395d9152ee" }, { "ImportPath": "github.com/spf13/cobra", "Rev": "312092086bed4968099259622145a0c9ae280064" }, { "ImportPath": "github.com/spf13/pflag", "Rev": "5644820622454e71517561946e3d94b9f9db6842" }, { "ImportPath": "github.com/stevvooe/resumable", "Rev": "51ad44105773cafcbe91927f70ac68e1bf78f8b4" }, { "ImportPath": "github.com/yvasiyarov/go-metrics", "Rev": "57bccd1ccd43f94bb17fdd8bf3007059b802f85e" }, { "ImportPath": "github.com/yvasiyarov/gorelic", "Comment": "v0.0.6-8-ga9bba5b", "Rev": "a9bba5b9ab508a086f9a12b8c51fab68478e2128" }, { "ImportPath": "github.com/yvasiyarov/newrelic_platform_go", "Rev": "b21fdbd4370f3717f3bbd2bf41c223bc273068e6" }, { "ImportPath": "golang.org/x/crypto/bcrypt", "Rev": "c10c31b5e94b6f7a0283272dc2bb27163dcea24b" }, { "ImportPath": "golang.org/x/crypto/blowfish", "Rev": "c10c31b5e94b6f7a0283272dc2bb27163dcea24b" }, { "ImportPath": "golang.org/x/net/context", "Rev": "1dfe7915deaf3f80b962c163b918868d8a6d8974" }, { "ImportPath": "gopkg.in/check.v1", "Rev": "64131543e7896d5bcc6bd5a76287eb75ea96c673" }, { "ImportPath": "gopkg.in/yaml.v2", "Rev": "bef53efd0c76e49e6de55ead051f886bea7e9420" } ]}
3.vendor
- golang1.5版本後加入vendor依賴包管理工具,還在試用階段,需要匯入環境變數export GO15VENDOREXPERIMENT=1,這樣做後就可以直接在編寫go代碼時匯入vendor目錄下的包而不用從gopath開始,比如docker1.9項目中,import “github.com/docker/distribution/digest”匯入的就是vendor目錄下的對應包
4._
底線
_
底線在golang中的使用
- 一種情況是佔位用的,方法返回兩個結果,而你只想要一個結果,那另一個就用 _ 佔位,而如果用變數的話,不使用,編譯器是會報錯的。
- 還有一種情況時類似於 import _ “fmt” 這種,import 一個包進來,但是不使用,只是讓包自己初始化一下,運行一下包內部的init()函數,否則匯入包不用也是會報錯的。但也要記住,這種情況下是不用調用包內其他的函數或者變數的。
5.查詢
5.1介面查詢
package twotype IStream insterface { Read(buf []byte) (n int, err error) Write(buf []byte) (n int, err error)}
package mainvar file1 Writer = new(File)if file5, ok := file1.(two.IStream); ok {}
上述代碼檢查file1介面指向的對象是否實現了two.IStream介面,如果實現了,則初始化file5並執行特定代碼。
5.2類型查詢
在Go語言中,還可以更加直截了當地詢問介面指向的對象執行個體類型,例如:
var v1 interface{} = ...switch v := v1.(type) { case int: //現在v的類型是int case string: //現在v的類型是string ...}
6. 包命名
項目的同一個目錄下只能有一個包名,所有檔案得用這個包名,不然會報錯。
7. 結構體和介面
- 當結構體的成員變數是結構體時,如果該結構體沒有賦值給具體的變數,那麼值就順延至新結構體;如果賦值給了新變數,那麼新變數就是新結構體的成員。
- 當一個結構體實現了介面的全部函數時,該結構就實現了這個介面,不一定要顯式聲明
- 介面類型作為具體的結構體成員,當為該結構體的介面類型賦值時賦的是已經實現了介面類型的結構
8. 作者介紹
梁明遠,國防科大並行與分散式運算國家重點實驗室(PDL)應屆研究生,14年入學伊始便開始接觸docker,準備在餘下的讀研時間在docker相關開源社區貢獻自己的代碼,畢業後準備繼續從事該方面研究。郵箱:liangmingyuanneo@gmail.com