【譯】使用 Go Modules

原文鏈接

介紹

本文是系列博客的第一部分盗飒。

  • Part 1 —— 使用 Go Modules (本文)
  • Part 2 —— 遷移到 Go Modules
  • Part 3 —— 發(fā)布 Go Modules
  • Part 4 —— Go Modules 的版本升級
  • Part 5 —— Go Modules 兼容

Go 1.11 版本初步添加了對 modules 特性的支持拓哟,作為 go 語言新的依賴管理系統(tǒng)斑举,可以幫助我們更明確、容易的管理依賴包的版本信息渤愁。在這篇文章中缰揪,我們將會介紹入門 modules 特性所需掌握的一些基本操作眨业。

module 是一系列包的集合竹握,以文件樹的形式記錄在go.mod文件中画株,該文件位于項目根路徑。go.mod文件主要定義了module的路徑(也就是使用該module的import路徑值)啦辐,以及該module本身對其他module的依賴信息谓传。其中每一個依賴項module都包含該module的導(dǎo)入路徑及專門的版本號,版本號要符合MAJOR.MINOR.PATCH格式昧甘。

從 Go 1.11 開始良拼,如果當前工作路徑或其父路徑下存在go.mod文件战得,且不在$GOPATH/src目錄內(nèi)的話充边,go 命令會默認使能modules特性,反之常侦,如果在$GOPATH/src目錄內(nèi)的話浇冰,為了兼容起見,go命令還會以傳統(tǒng)的GOPATH模式運作聋亡,即便有g(shù)o.mod文件存在肘习。但從 Go 1.13 開始,module模式將會成為默認模式坡倔。即不管當前路徑是否位于$GOPATH/src路徑下漂佩,只要含go.mod文件則默認開啟module模式,除非你修改了環(huán)境變量GO111MODULE值罪塔,將其置為了off 投蝉。

本文將會從以下幾個步驟來介紹使用 modules 特性開發(fā)過程中所涉及的幾個通用操作:

  • 創(chuàng)建一個新的 module
  • 為該 module 添加一個依賴
  • 升級依賴
  • 升級 module 大版本后,添加一個新的依賴
  • 升級 module 大版本后征堪,更新一個已有的依賴
  • 移除冗余的依賴項

創(chuàng)建一個新的 module

現(xiàn)在我們開始創(chuàng)建一個新的 module 瘩缆。
$GOPATH/src目錄外部某個路徑,新建一個空的文件夾佃蚜,并創(chuàng)建一個hello.go文件:

package hello

func Hello() string {
    return "Hello, world."
}

同時庸娱,添加測試代碼文件hello_test.go:

package hello

import "testing"

func TestHello(t *testing.T) {
    want := "Hello, world."
    if got := Hello(); got != want {
        t.Errorf("Hello() = %q, want %q", got, want)
    }
}

此時,這個目錄下包含一個包——hello谐算,但因為沒有g(shù)o.mod文件熟尉,所以還算不上是一個module,這時候我們運行go test命令可以看到:

C:\Users\Lenovo\IdeaProjects\studyGoModules>go test
PASS
ok      _/C_/Users/Lenovo/IdeaProjects/studyGoModules   0.240s

C:\Users\Lenovo\IdeaProjects\studyGoModules>

很奇怪洲脂,我們既沒有在$GOPATH/src目錄下工作斤儿,同時當前目錄也沒有g(shù)o.mod文件,按理說hello_test.go會報找不到Hello()方法的錯誤,但為啥跑過了呢雇毫?原來是go命令找不到任何路徑玄捕,于是基于其當前工作路徑名編造了一個假的的導(dǎo)入path:_/C_/Users/Lenovo/IdeaProjects/studyGoModules,通過這種方法棚放,他找到了hello.go文件中定義的Hello()方法枚粘,使得測試跑過了。

接下來飘蚯,我們通過命令go mod init來創(chuàng)建一個根路徑為當前路徑的module并且再次執(zhí)行go test查看效果:

C:\Users\Lenovo\IdeaProjects\studyGoModules>go mod init gitee.com/atix/hello
go: creating new go.mod: module gitee.com/atix/hello

C:\Users\Lenovo\IdeaProjects\studyGoModules>go test
PASS
ok      gitee.com/atix/hello    0.244s

C:\Users\Lenovo\IdeaProjects\studyGoModules>

可以看到我們創(chuàng)建了一個名為```gitee.com/atix/hello``的module馍迄,并且測試了這個module的可用性。同時還在當前路徑創(chuàng)建了一個go.mod文件:

module gitee.com/atix/hello

go 1.14

go.mod文件只會出現(xiàn)在一個module的根路徑下局骤。我們可以在某個module目錄中新建子目錄并創(chuàng)建新的package攀圈,只需在引用該package時,import路徑包含上module的import路徑即可峦甩。如:我們上面創(chuàng)建了一個新的module:gitee.com/atix/hello赘来,我們在根目錄下新建文件夾:subHello,并新建文件subHello.go:

package subHello

import "fmt"

func SubHello() string {
    return "SubHello, world!"
}

這樣凯傲,當我們需要在別的地方使用SubHello()方法時(當然犬辰,首先我們得發(fā)布hello module),import路徑要加上hello module的路徑冰单,即:

import "gitee.com/atix/hello/subHello"

為該 module 添加一個依賴

Go Modules 的主要目的是更好的使用其他開發(fā)者開發(fā)的代碼幌缝。
接下來我們嘗試在hello module中使用其他開發(fā)者發(fā)布的module,首先我們改寫一下hello.go:

package hello

import "rsc.io/quote"

func Hello() string {
    return quote.Hello()
}

然后我們再次運行go test命令看下效果(因本人網(wǎng)絡(luò)問題訪問https://proxy.golang.org/rsc.io/quote/@v/list 異常诫欠,故此處貼原文執(zhí)行效果):

$ go test
go: finding rsc.io/quote v1.5.2
go: downloading rsc.io/quote v1.5.2
go: extracting rsc.io/quote v1.5.2
go: finding rsc.io/sampler v1.3.0
go: finding golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: downloading rsc.io/sampler v1.3.0
go: extracting rsc.io/sampler v1.3.0
go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: extracting golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
PASS
ok      gitee.com/atix/hello    0.023s
$

這里我找到了rsc.io/quote的go.mod文件:

module "rsc.io/quote"

require "rsc.io/sampler" v1.3.0

以及rsc.io/sampler的go.mod文件:

module "rsc.io/sampler"

require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c

可以看到涵卵,從hello到quote,再到sampler荒叼,依次依賴了下面3個module:

  • rsc.io/quote v1.5.2
  • rsc.io/sampler v1.3.0
  • golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c

同時我們可以在go test的執(zhí)行日志中看到這3個module的find->downloading->extract操作轿偎,即:go 命令會分析go.mod文件,并遞歸式的處理require模塊所聲明的依賴項module甩挫,處理內(nèi)容包括下載及解壓贴硫,解壓后的依賴項module內(nèi)容會緩存在$GOPATH/pkg/mod路徑中。

go test執(zhí)行的效果還包括:將解析后的依賴項module信息添加到本module的go.mod文件中伊者,注意英遭,默認只添加直接依賴的module。關(guān)于依賴項module的版本號亦渗,默認使用其最新版本挖诸。體現(xiàn)為:

$ cat go.mod
module gitee.com/atix/hello

go 1.14

require rsc.io/quote v1.5.2
$

值得注意的是,雖然 go 命令使得添加依賴變得超級方便法精,但這是有代價的多律。你會發(fā)現(xiàn)自己的模塊在某些關(guān)鍵領(lǐng)域痴突,比如說正確性、安全性以及許可性等方面會相當依賴新添加的依賴項modules狼荞。這方面想了解更多的話辽装,可以參閱博客Our Software Dependency Problem

正如上面我們看到的那樣相味,添加一個直接依賴的同時也會帶來一些間接依賴拾积。執(zhí)行命令go list -m all可以查看當前module的所有依賴項信息:

$ go list -m all
gitee.com/atix/hello
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
rsc.io/quote v1.5.2
rsc.io/sampler v1.3.0
$

注意此命令會遞歸式分析go.mod文件,如果你跟我一樣因網(wǎng)絡(luò)原因執(zhí)行go test失敗導(dǎo)致go.mod文件沒更新的話丰涉,此命令只會顯示本module(別名:主 module )信息拓巧,即上面的第一行:gitee.com/atix/hello 。
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c :此依賴項版本號被稱為"Pseudo-versions"式版本號一死,代表該module代碼的某次提交版本肛度,該提交尚未打tag,由3部分組成投慈,代碼提交前最近的一次版本號承耿,代碼提交時間的UTC格式,以及代碼提交號的hash前綴逛裤。更多詳情戳此

除了go.mod文件外瘩绒,go命令還維護了一個名為go.sum的文件猴抹,該文件主要包含各依賴項module版本內(nèi)容的加密哈希值带族。如果未依賴其他module則不會生成go.sum文件。

$ cat go.sum
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZO...
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:Nq...
rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3...
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPX...
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/Q...
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9...
$

借助于go.sum文件的幫助蟀给,go命令可以確保將來下載這些module的代碼時能夠獲取跟第一次下載時相同的內(nèi)容蝙砌,以保證你的項目依賴的這些module不會發(fā)生意想不到的改變,不管是惡意的跋理,偶然的還是意外的择克。故,請將go.mod前普、go.sum文件都納入版本管理肚邢。

升級依賴

使用 Go Modules 功能過程中,版本號要符合一定的語法格式拭卿。一個合法格式包括3部分:主版本骡湖、次版本、補丁版本峻厚。舉個例子响蕴,拿v0.1.2來說,主版本號是0惠桃,次版本號是1浦夷,補丁版本是2辖试。接下來,我們一起來對gitee.com/atix/hello進行一次次版本號升級劈狐。

通過分析命令go list -m all的輸出結(jié)果罐孝,我們可以看到golang.org/x/text模塊的版本是一個未打tag的版本號,接下來我們把 golang.org/x/text升級到最新的一個tag版本并測試一下項目是否依然有效:

$ go get golang.org/x/text
go: finding golang.org/x/text v0.3.0
go: downloading golang.org/x/text v0.3.0
go: extracting golang.org/x/text v0.3.0
$ go test
PASS
ok      example.com/hello   0.013s
$

關(guān)于命令go get肥缔,完整的命令肾档,在module名后面需要加上@version字段來指明要獲取該module哪個版本,默認情況下會獲取其最新版本

很棒辫继,項目運行正常怒见,接下來讓我再看一眼項目的依賴情況是否發(fā)生了變化:

$ go list -m all
example.com/hello
golang.org/x/text v0.3.0
rsc.io/quote v1.5.2
rsc.io/sampler v1.3.0
$ cat go.mod
module gitee.com/atix/hello

go 1.12

require (
    golang.org/x/text v0.3.0 // indirect
    rsc.io/quote v1.5.2
)
$

注釋// indirect表示這一行的依賴并不是本module直接依賴使用的,而是其他module依賴使用的姑宽。想了解更多的話可以執(zhí)行命令go help modules來查看細節(jié)遣耍。

可以看到golang.org/x/text已經(jīng)升級到了最新的版本,同時go.mod文件也更新了炮车,增加了golang.org/x/text模塊的描述信息舵变,前面我們提到過,默認情況下執(zhí)行go test時瘦穆,go.mod文件只會加載直接依賴的module信息纪隙,為啥這次把golang.org/x/text這個間接依賴的module信息加上了呢,這是因為我們在本地執(zhí)行了go get golang.org/x/text命令后扛或,本地開發(fā)調(diào)試用到該module的代碼時都會用本地的最新版本golang.org/x/text代碼绵咱,而不是之前那個未打tag的版本,這種情況下熙兔,如果我們發(fā)布了自己的module悲伶,別人引用時,才能正常使用住涉。

需要注意的是麸锉,通過本地go get方式直接覆蓋原依賴module版本時會出現(xiàn)不兼容問題,換句話說舆声,本來以來的那個module版本是v1.1.0花沉,但你通過go get方式獲取的是v1.2.0,且該module的v1.2.0未兼容v1.1.0媳握,那么使用時就會出錯碱屁。因此,如果想要本地升級某個依賴module的版本毙芜,最好在get的時候指定某個具體的版本忽媒,如:go get rsc.io/sampler@v1.3.1

命令go list -m -versions ${module_name}可以列出${module_name}所有可用版本

添加一個新的依賴,該依賴是某個已有依賴module的大版本升級中引入的特性

截止目前為止腋粥,我們的gitee.com/atix/hello模塊直接依賴的module只有一個rsc.io/quote v1.5.2晦雨,接下來我們將要引入一個新的module:rsc.io/quote/v3@latest架曹,并在我們代碼中調(diào)用其Concurrency()方法,修改hello.go文件如下:

package hello

import (
    "rsc.io/quote"
    v3 "rsc.io/quote/v3"
)

func Hello() string {
    return quote.Hello()
}

func V3Hello() string {
    return v3.Concurrency()
}

同時在測試代碼中添加對新方法V3Hello()的測試方法:

package hello

import "testing"

func TestHello(t *testing.T) {
    want := "Hello, world."
    if got := Hello(); got != want {
        t.Errorf("Hello() = %q, want %q", got, want)
    }
}

func TestV3Hello(t *testing.T) {
    want := "Concurrency is not parallelism."
    if got := V3Hello(); got != want {
        t.Errorf("V3Hello() = %s, want %s", got, want)
    }
}

接下來執(zhí)行go test查看效果:

$ go test
go: finding rsc.io/quote/v3 v3.1.0
go: downloading rsc.io/quote/v3 v3.1.0
go: extracting rsc.io/quote/v3 v3.1.0
PASS
ok      gitee.com/atix/hello    0.024s
$

此時闹瞧,如果我們查看go.mod文件時绑雄,會發(fā)現(xiàn)require塊同時包含rsc.io/quote v1.5.2和rsc.io/quote/v3 v3.1.0兩行,那么這個要怎么理解呢奥邮?

回顧我們本段標題万牺,什么叫升級大版本?對于每一個module來說洽腺,主版本升級意味著不同的module path脚粟,從v2開始,每升級一個大版本蘸朋,該module的import路徑都要加一層核无。拿本例中的rsc.io/quote來說,第一次我們import時寫的是import rsc.io/quote藕坯,那么當go命令在解析依賴關(guān)系時团南,就回去拉rsc.io/quote第一個大版本的最新版,即v1.3.2炼彪,后來我們新import了import rsc.io/quote/v3吐根,那么當go命令在解析依賴關(guān)系時,就回去拉rsc.io/quote第三個大版本的最新版辐马,即v3.1.0拷橘。

這是go語言對module版本的語法定義,默認情況下齐疙,同一個大版本內(nèi)的小版本之間膜楷,應(yīng)該是向下兼容的。這樣如果我們之前依賴了某個module的低版本贞奋,當后期需要升級其次版本號以使用某個新增的方法或者特性時,就不需要修改import的path穷绵,只需要執(zhí)行go get XXX@YYY來獲取其新的版本即可轿塔。

對于同一個module path,在同一次build中仲墨,go命令最多只允許include一次勾缭。通過變更module path的方式來升級大版本號可以允許我們在一次build同時include該module的多個版本,因為他們的module path不同目养。這在某些時候尤其有用俩由,想象這樣一種場景,作為使用方癌蚁,我們在項目中依賴了某個module A幻梯,某天A升級了大版本兜畸,添加了某個有用的特性,但新版本是否兼容了舊版本尚未可知碘梢,此時我們既想用新特性咬摇,又沒有那么多時間去驗證之前使用部分的兼容性,怎么辦煞躬,沒關(guān)系肛鹏,只要A遵循了大版本升級修改module path的原則,那么我們可以在項目中同時使用A新舊兩個版本恩沛,只需要在import時對新版本加個別名即可在扰,如前面我們的做法:import v3 rsc.io/quote/v3 就是給quote的大版本3起了個別名v3。

將已有的某個依賴module升級到其新的大版本

上一節(jié)中雷客,我們同時引入了rsc.io/quote的v1和v3兩個版本健田,雖然在當時是方便了,但現(xiàn)在我們想要簡化依賴樹佛纫,僅使用rsc.io/quote的最新版本妓局。這時候我們要考慮至少以下幾個方面,大版本升級后:

  • 低版本中的接口是否被移除
  • 是否命名變了
  • 是否出入?yún)⒆兞?/li>

此時最直接的方法通讀rsc.io/quote/v3的更新文檔來了解呈宇,查閱某個module的文檔可以通過執(zhí)行go doc命令實現(xiàn):

$ go doc rsc.io/quote/v3
package quote // import "rsc.io/quote/v3"

Package quote collects pithy sayings.

func Concurrency() string
func GlassV3() string
func GoV3() string
func HelloV3() string
func OptV3() string
$

可以看到rsc.io/quote/v3中已不再有Hello()方法好爬,新的方法名為HelloV3(),此時我們修改我們項目中對Hello()方法的使用甥啄,如下:

package hello

import v3 "rsc.io/quote/v3"

func Hello() string {
    return v3.HelloV3()
}

func V3Hello() string {
    return v3.Concurrency()
}

注意對比兩個版本的hello.go存炮,變化有兩個地方:

  • import處移除了對rsc.io/quote的引用
  • 方法Hello()中有原先的return quote.Hello()改為了return v3.HelloV3(),包名和方法名都做了變更

至此蜈漓,我們項目中對rsc.io/quote的依賴就變成單一的rsc.io/quote/v3了穆桂,就不再需要在import對其進行別名處理了:

package hello

import "rsc.io/quote/v3"

func Hello() string {
    return quote.HelloV3()
}

func Proverb() string {
    return quote.Concurrency()
}

這里有個小插曲,樓主這邊是用的是IDEA融虽,該工具在判斷import包的使用情況時比較死板享完,只認最后一層路徑,他發(fā)現(xiàn)你沒有使用v3有额,就會把import那行給刪掉般又,坑爹

移除未使用的依賴

雖然上面我們刪掉了rsc.io/quote的導(dǎo)入,但當我們執(zhí)行go list -m all或者查看go.mod文件時巍佑,發(fā)現(xiàn)其仍然存在:

$ go list -m all
gitee.com/atix/hello
golang.org/x/text v0.3.0
rsc.io/quote v1.5.2
rsc.io/quote/v3 v3.1.0
rsc.io/sampler v1.3.1
$ cat go.mod
module gitee.com/atix/hello

go 1.14

require (
    golang.org/x/text v0.3.0 // indirect
    rsc.io/quote v1.5.2
    rsc.io/quote/v3 v3.0.0
    rsc.io/sampler v1.3.1 // indirect
)
$

這是為何茴迁?原來當我們通過命令go build或go test構(gòu)建某個獨立的包時,go命令知會檢查是否有包丟失了萤衰,或者需要添加進來堕义,但卻不會移除冗余的包。想要移除冗余的module信息可以執(zhí)行命令go mod tidy來實現(xiàn):

$ go mod tidy
$ go list -m all
gitee.com/atix/hello
golang.org/x/text v0.3.0
rsc.io/quote/v3 v3.1.0
rsc.io/sampler v1.3.1
$ cat go.mod
module gitee.com/atix/hello

go 1.14

require (
    golang.org/x/text v0.3.0 // indirect
    rsc.io/quote/v3 v3.1.0
    rsc.io/sampler v1.3.1 // indirect
)

$ go test
PASS
ok      gitee.com/atix/hello    0.020s
$

總結(jié)

Go Modules 是未來 Go 語言的依賴管理體系脆栋,且此特性在 Go 1.11 之后均支持倦卖。

圍繞go.mod文件洒擦,本文介紹了使用 Go Modules 時涉及的幾個命令:

  • go mod init 創(chuàng)建一個新的module,并初始化go.mod文件
  • go build, go test 將新增的依賴module信息加載到go.mod文件中
  • go list -m all解析go.mod文件并打印當前module的依賴信息
  • go get可以用來修改或者新增某個依賴module信息
  • go mod tidy可以移除冗余的module信息

在實際開發(fā)過程中糖耸,我們提倡大家使用modules特性秘遏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市嘉竟,隨后出現(xiàn)的幾起案子邦危,更是在濱河造成了極大的恐慌,老刑警劉巖舍扰,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件倦蚪,死亡現(xiàn)場離奇詭異,居然都是意外死亡边苹,警方通過查閱死者的電腦和手機陵且,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來个束,“玉大人慕购,你說我怎么就攤上這事〔绲祝” “怎么了沪悲?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長阱表。 經(jīng)常有香客問我殿如,道長,這世上最難降的妖魔是什么最爬? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任涉馁,我火速辦了婚禮,結(jié)果婚禮上爱致,老公的妹妹穿的比我還像新娘烤送。我一直安慰自己,他們只是感情好蒜鸡,可當我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布胯努。 她就那樣靜靜地躺著,像睡著了一般逢防。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蒲讯,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天忘朝,我揣著相機與錄音,去河邊找鬼判帮。 笑死局嘁,一個胖子當著我的面吹牛溉箕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播悦昵,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼肴茄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了但指?” 一聲冷哼從身側(cè)響起寡痰,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎棋凳,沒想到半個月后拦坠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡剩岳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年贞滨,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拍棕。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡晓铆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出绰播,到底是詐尸還是另有隱情骄噪,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站澜公,受9級特大地震影響弦讽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜示弓,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望呵萨。 院中可真熱鬧奏属,春花似錦、人聲如沸潮峦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忱嘹。三九已至嘱腥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拘悦,已是汗流浹背齿兔。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人分苇。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓添诉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親医寿。 傳聞我的和親對象是個殘疾皇子栏赴,可洞房花燭夜當晚...
    茶點故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Go的1.11和1.12版本包括對模塊--新的Go依賴管理系統(tǒng)的初步支持,使依賴版本信息變得明確且更易于管理靖秩。這篇...
    Java天天閱讀 2,804評論 0 1
  • 一须眷,module的來源定義 go1.11和go1.12對golang的 module做了一個試水,從go1.13開...
    舒小賤閱讀 1,525評論 0 0
  • Go 1.11 Modules翻譯自 Go 官方wiki # Go 1.11 Modules 根據(jù)[提議](htt...
    drawing818閱讀 1,444評論 0 0
  • 簡介 go 1.11以后提供了新的管理依賴的方式, 使得管理依賴,尤其是依賴版本更加的明確且易于管理, 這種方式就...
    allenhaozi閱讀 1,489評論 0 1
  • 前言 mod 是 modules 的簡稱盆偿,Go 1.11 和 Go 1.12 早已支持 modules柒爸。在 Go ...
    吃豬的蛇閱讀 1,386評論 0 6