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 two
type IStream insterface {
Read(buf []byte) (n int, err error)
Write(buf []byte) (n int, err error)
}
package main
var 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
有疑问加站长微信联系(非本文作者)