回到简体

This commit is contained in:
chai2010
2016-02-15 11:06:34 +08:00
parent 9e878f9944
commit 2b37b23285
177 changed files with 2354 additions and 2354 deletions

View File

@@ -1,9 +1,9 @@
## 10.1. 包
## 10.1. 包
任何包繫統設計的目的都是爲了簡化大型程序的設計和維護工作,通過將一組相關的特性放進一個獨立的元以便理解和更新,在每個單元更新的同保持和程序中其它元的相對獨立性。這種模塊化的特性允許每個包可以被其它的不同目共享和重用,在目范圍內、甚至全球范圍統一的分發和複用。
任何包系统设计的目的都是为了简化大型程序的设计和维护工作,通过将一组相关的特性放进一个独立的元以便理解和更新,在每个单元更新的同保持和程序中其它元的相对独立性。这种模块化的特性允许每个包可以被其它的不同目共享和重用,在目范围内、甚至全球范围统一的分发和复用。
包一般都定了一不同的名字空間用於它內部的每個標識符的訪問。每名字空間關聯到一特定的包,讓我們給類型、函數等選擇簡短明了的名字,這樣可以避免在我使用它們的時候減少和其它部分名字的突。
包一般都定了一不同的名字空间用于它内部的每个标识符的访问。每名字空间关联到一特定的包,让我们给类型、函数等选择简短明了的名字,这样可以避免在我使用它们的时候减少和其它部分名字的突。
個包還通過控製包內名字的可性和是否導出來實現封裝特性。通過限製包成的可見性併隱藏包API的具體實現,將允許包的維護者在不影外部包用的前提下調整包的內部實現。通過限製包內變量的可性,可以強製用戶通過某些特定函數來訪問和更新內部變量,這樣可以保證內部變量的一致性和併發時的互斥束。
个包还通过控制包内名字的可性和是否导出来实现封装特性。通过限制包成的可见性并隐藏包API的具体实现,将允许包的维护者在不影外部包用的前提下整包的内部实现。通过限制包内变量的可性,可以强制用户通过某些特定函数来访问和更新内部变量,这样可以保证内部变量的一致性和并发时的互斥束。
當我們脩改了一源文件,我們必須重新編譯該源文件對應的包和所有依賴該包的其他包。使是從頭構Go語言編譯器的編譯速度也明顯快於其它編譯語言。Go言的閃電般的編譯速度主要得益於三個語言特性。第一,所有入的包必在每文件的開頭顯式聲明,這樣的話編譯器就有必要取和分析整源文件來判斷包的依賴關繫。第二,禁止包的環狀依賴,因爲沒有循環依賴,包的依賴關繫形成一有向無環圖,每包可以被獨立編譯,而且很可能是被併發編譯。第三點,編譯後包的目文件不僅僅記録包本身的出信息,目文件同時還記録了包的依賴關繫。因此,在編譯一個包的候,編譯器隻需要取每直接入包的目文件,而不需要遍所有依的的文件(譯註:很多都是重複的間接依)。
当我们修改了一源文件,我们必须重新编译该源文件对应的包和所有依赖该包的其他包。使是从头构Go语言编译器的编译速度也明显快于其它编译语言。Go言的闪电般的编译速度主要得益于三个语言特性。第一,所有入的包必在每文件的开头显式声明,这样的话编译器就有必要取和分析整源文件来判断包的依赖关系。第二,禁止包的环状依赖,因为没有循环依赖,包的依赖关系形成一有向无环图,每包可以被独立编译,而且很可能是被并发编译。第三点,编译后包的目文件不仅仅记录包本身的出信息,目文件同时还记录了包的依赖关系。因此,在编译一个包的候,编译器只需要取每直接入包的目文件,而不需要遍所有依的的文件(译注:很多都是重复的间接依)。

View File

@@ -1,6 +1,6 @@
## 10.2. 入路
## 10.2. 入路
包是由一全局唯一的字符串所標識的導入路定位。出在import句中的入路也是字符串。
包是由一全局唯一的字符串所标识的导入路定位。出在import句中的入路也是字符串。
```Go
import (
@@ -14,6 +14,6 @@ import (
)
```
就像我在2.6.1提到Go言的規范併沒有指明包的入路字符串的具體含義,導入路的具體含義是由建工具來解釋的。在本章,我們將深入討論Go言工具箱的功能,包括大家常使用的構建測試等功能。然,也有第三方展的工具箱存在。例如Google公司部的Go語言碼農,他就使用部的多語言構建繫統(譯註Google公司使用的是似[Bazel](http://bazel.io)的構建繫統,支持多種編程語言,目前該構件繫統還不能完整支持Windows境),用不同的規則來處理包名字和定位包,用不同的規則來處理單元測試等等,因爲這樣可以更緊密適配他們內部環境。
就像我在2.6.1提到Go言的规范并没有指明包的入路字符串的具体含义,导入路的具体含义是由建工具来解释的。在本章,我们将深入讨论Go言工具箱的功能,包括大家常使用的构建测试等功能。然,也有第三方展的工具箱存在。例如Google公司部的Go语言码农,他就使用部的多语言构建系统(译注Google公司使用的是似[Bazel](http://bazel.io)的构建系统,支持多种编程语言,目前该构件系统还不能完整支持Windows境),用不同的规则来处理包名字和定位包,用不同的规则来处理单元测试等等,因为这样可以更紧密适配他们内部环境。
如果你計劃分享或布包,那麽導入路最好是全球唯一的。了避免突,所有非標準庫包的入路徑建議以所在組織的互聯網域名爲前綴;而且這樣也有利包的索。例如上面的import語句導入了Go糰隊維護的HTML解析器和一流行的第三方維護的MySQL驅動
如果你计划分享或布包,那么导入路最好是全球唯一的。了避免突,所有非标准库包的入路径建议以所在组织的互联网域名为前缀;而且这样也有利包的索。例如上面的import语句导入了Go团队维护的HTML解析器和一流行的第三方维护的MySQL驱动

View File

@@ -1,8 +1,8 @@
## 10.3. 包
## 10.3. 包
在每Go音源文件的開頭都必有包聲明語句。包聲明語句的主要目的是確定當前包被其它包導入時默認的標識符(也稱爲包名)。
在每Go音源文件的开头都必有包声明语句。包声明语句的主要目的是确定当前包被其它包导入时默认的标识符(也称为包名)。
例如math/rand包的每源文件的開頭都包含`package rand`聲明語句,所以當你導入這個你就可以用rand.Int、rand.Float64似的方式訪問包的成
例如math/rand包的每源文件的开头都包含`package rand`声明语句,所以当你导入这个你就可以用rand.Int、rand.Float64似的方式访问包的成
```Go
package main
@@ -17,10 +17,10 @@ func main() {
}
```
通常來説,默的包名就是包入路名的最一段,因此卽使兩個包的入路不同,它依然可能有一相同的包名。例如math/rand包和crypto/rand包的包名都是rand。稍後我們將看到如何同時導入兩個有相同包名的包。
通常来说,默的包名就是包入路名的最一段,因此即使两个包的入路不同,它依然可能有一相同的包名。例如math/rand包和crypto/rand包的包名都是rand。稍后我们将看到如何同时导入两个有相同包名的包。
關於默認包名一般采用入路名的最一段的定也有三例外情。第一例外,包對應一個可執行程序也就是main包這時候main包本身的入路徑是無關緊要的。名字main的包是go build§10.7.3建命令一信息,這個包編譯完之後必須調用連接器生成一個可執行程序。
关于默认包名一般采用入路名的最一段的定也有三例外情。第一例外,包对应一个可执行程序也就是main包这时候main包本身的入路径是无关紧要的。名字main的包是go build§10.7.3建命令一信息,这个包编译完之后必须调用连接器生成一个可执行程序。
第二例外,包所在的目中可能有一些文件名是以_test.go爲後綴的Go源文件譯註:前面必有其它的字符,因`_`的源文件是被忽略的),併且這些源文件明的包名也是以_test爲後綴名的。這種目録可以包含兩種包:一普通包,加一種則是測試的外部展包。所有以_test爲後綴包名的測試外部展包都由go test命令獨立編譯,普通包和測試的外部展包是相互立的。測試的外部展包一般用避免測試代碼中的循環導入依,具體細節我們將在11.2.4中介
第二例外,包所在的目中可能有一些文件名是以_test.go为后缀的Go源文件译注:前面必有其它的字符,因`_`的源文件是被忽略的),并且这些源文件明的包名也是以_test为后缀名的。这种目录可以包含两种包:一普通包,加一种则是测试的外部展包。所有以_test为后缀包名的测试外部展包都由go test命令独立编译,普通包和测试的外部展包是相互立的。测试的外部展包一般用避免测试代码中的循环导入依,具体细节我们将在11.2.4中介
第三例外,一些依版本的管理工具會在導入路徑後追加版本信息,例如"gopkg.in/yaml.v2"。這種情況下包的名字不包含版本號後綴而是yaml。
第三例外,一些依版本的管理工具会在导入路径后追加版本信息,例如"gopkg.in/yaml.v2"。这种情况下包的名字不包含版本号后缀而是yaml。

View File

@@ -1,6 +1,6 @@
## 10.4. 導入聲
## 10.4. 导入声
可以在一Go言源文件包聲明語句之,其它非導入聲明語句之前,包含零到多個導入包聲明語句。每個導入聲明可以單獨指定一個導入路,也可以通過圓括號同時導入多個導入路。下面兩個導入形式是等的,但是第二形式更爲常見
可以在一Go言源文件包声明语句之,其它非导入声明语句之前,包含零到多个导入包声明语句。每个导入声明可以单独指定一个导入路,也可以通过圆括号同时导入多个导入路。下面两个导入形式是等的,但是第二形式更为常见
```Go
import "fmt"
@@ -12,7 +12,7 @@ import (
)
```
入的包之可以通添加空行來分組;通常將來自不同組織的包自分。包的導入順序無關緊要,但是在每個分組中一般會根據字符串序排列。gofmt和goimports工具都可以不同分組導入的包立排序。)
入的包之可以通添加空行来分组;通常将来自不同组织的包自分。包的导入顺序无关紧要,但是在每个分组中一般会根据字符串序排列。gofmt和goimports工具都可以不同分组导入的包立排序。)
```Go
import (
@@ -25,7 +25,7 @@ import (
)
```
如果我想同時導入兩個有着名字相同的包例如math/rand包和crypto/rand包麽導入聲明必至少爲一個同名包指定一新的包名以避免突。叫做入包的重命名。
如果我想同时导入两个有着名字相同的包例如math/rand包和crypto/rand包么导入声明必至少为一个同名包指定一新的包名以避免突。叫做入包的重命名。
```Go
import (
@@ -34,8 +34,8 @@ import (
)
```
入包的重命名隻影響當前的源文件。其它的源文件如果入了相同的包,可以用入包原本默的名字或重命名另一完全不同的名字。
入包的重命名只影响当前的源文件。其它的源文件如果入了相同的包,可以用入包原本默的名字或重命名另一完全不同的名字。
入包重命名是一有用的特性,它不僅僅隻是爲了解名字突。如果入的一包名很笨重,特别是在一些自生成的代中,這時候用一個簡短名稱會更方便。選擇用簡短名重命名入包候最好一,以避免包名混亂。選擇另一包名稱還可以助避免和本地普通量名産生衝突。例如,如果文件中已有了一個名爲path的量,那麽我們可以"path"標準包重命名pathpkg。
入包重命名是一有用的特性,它不仅仅只是为了解名字突。如果入的一包名很笨重,特别是在一些自生成的代中,这时候用一个简短名称会更方便。选择用简短名重命名入包候最好一,以避免包名混乱。选择另一包名称还可以助避免和本地普通量名产生冲突。例如,如果文件中已有了一个名为path的量,那么我们可以"path"标准包重命名pathpkg。
個導入聲明語句都明指定了前包和被入包之的依賴關繫。如果遇到包循環導入的情Go言的建工具將報告錯誤
个导入声明语句都明指定了前包和被入包之的依赖关系。如果遇到包循环导入的情Go言的建工具将报告错误

View File

@@ -1,14 +1,14 @@
## 10.5. 包的匿名
## 10.5. 包的匿名
如果隻是導入一包而不使用入的包將會導致一個編譯錯誤。但是有候我們隻是想利用入包而生的副作用:它會計算包級變量的初始化表式和執行導入包的init初始化函§2.6.2)。這時候我需要抑“unused import”編譯錯誤,我可以用下劃線`_`重命名入的包。像往常一,下劃線`_`空白標識符,不能被訪問
如果只是导入一包而不使用入的包将会导致一个编译错误。但是有候我们只是想利用入包而生的副作用:它会计算包级变量的初始化表式和执行导入包的init初始化函§2.6.2)。这时候我需要抑“unused import”编译错误,我可以用下划线`_`重命名入的包。像往常一,下划线`_`空白标识符,不能被访问
```Go
import _ "image/png" // register PNG decoder
```
這個被稱爲包的匿名入。它通常是用來實現一個編譯時機製,然後通過在main主程序入口選擇性地入附加的包。首先,讓我們看看如何使用特性,然再看看它是如何工作的。
这个被称为包的匿名入。它通常是用来实现一个编译时机制,然后通过在main主程序入口选择性地入附加的包。首先,让我们看看如何使用特性,然再看看它是如何工作的。
標準庫的image像包包含了一`Decode`,用於從`io.Reader`接口讀取數據併解碼圖像,它調用底層註冊的圖像解碼器來完成任,然後返迴image.Image型的像。使用`image.Decode`很容易編寫一個圖像格式的轉換工具,取一格式的像,然後編碼爲另一種圖像格式:
标准库的image像包包含了一`Decode`,用于从`io.Reader`接口读取数据并解码图像,它用底层注册的图像解码器来完成任,然后返回image.Image型的像。使用`image.Decode`很容易编写一个图像格式的转换工具,取一格式的像,然后编码为另一种图像格式:
<u><i>gopl.io/ch10/jpeg</i></u>
```Go
@@ -42,7 +42,7 @@ func toJPEG(in io.Reader, out io.Writer) error {
}
```
如果我們將`gopl.io/ch3/mandelbrot`§3.3)的輸出導入到這個程序的標準輸入,它將解碼輸入的PNG格式像,然後轉換爲JPEG格式的圖像輸出(3.3)。
如果我们将`gopl.io/ch3/mandelbrot`§3.3)的输出导入到这个程序的标准输入,它将解码输入的PNG格式像,然后转换为JPEG格式的图像输出(3.3)。
```
$ go build gopl.io/ch3/mandelbrot
@@ -51,7 +51,7 @@ $ ./mandelbrot | ./jpeg >mandelbrot.jpg
Input format = png
```
意image/png包的匿名導入語句。如果沒有這一行句,程序依然可以編譯和運行,但是它不能正確識别和解PNG格式的像:
意image/png包的匿名导入语句。如果没有这一行句,程序依然可以编译和运行,但是它不能正确识别和解PNG格式的像:
```
$ go build gopl.io/ch10/jpeg
@@ -59,7 +59,7 @@ $ ./mandelbrot | ./jpeg >mandelbrot.jpg
jpeg: image: unknown format
```
下面的代演示了它的工作機製。標準庫還提供了GIF、PNG和JPEG等格式像的解器,用也可以提供自己的解器,但是了保持程序體積較小,很多解碼器併沒有被全部包含,除非是明需要支持的格式。image.Decode函在解碼時會依次査詢支持的格式列表。每格式驅動列表的每入口指定了四件事情:格式的名;一個用於描述這種圖像數據開頭部分模式的字符串,用於解碼器檢測識别;一Decode函數用於完成解碼圖像工作;一DecodeConfig函數用於解碼圖像的大小和色空的信息。每個驅動入口是通過調用image.RegisterFormat函數註冊,一般是在每格式包的init初始化函數中調例如image/png包是這樣註冊的:
下面的代演示了它的工作机制。标准库还提供了GIF、PNG和JPEG等格式像的解器,用也可以提供自己的解器,但是了保持程序体积较小,很多解码器并没有被全部包含,除非是明需要支持的格式。image.Decode函在解码时会依次查询支持的格式列表。每格式驱动列表的每入口指定了四件事情:格式的名;一个用于描述这种图像数据开头部分模式的字符串,用于解码器检测识别;一Decode函数用于完成解码图像工作;一DecodeConfig函数用于解码图像的大小和色空的信息。每个驱动入口是通过调用image.RegisterFormat函数注册,一般是在每格式包的init初始化函数中调例如image/png包是这样注册的:
```Go
package png // image/png
@@ -73,9 +73,9 @@ func init() {
}
```
的效果是,主程序需要匿名入特定圖像驅動包就可以用image.Decode解碼對應格式的像了。
的效果是,主程序需要匿名入特定图像驱动包就可以用image.Decode解码对应格式的像了。
數據庫包database/sql也是采用了似的技術,讓用戶可以根自己需要選擇導入必要的數據庫驅動。例如:
数据库包database/sql也是采用了似的技术,让用户可以根自己需要选择导入必要的数据库驱动。例如:
```Go
import (
@@ -89,6 +89,6 @@ db, err = sql.Open("mysql", dbname) // OK
db, err = sql.Open("sqlite3", dbname) // returns error: unknown driver "sqlite3"
```
**練習 10.1** 展jpeg程序以支持任意像格式之的相互轉換使用image.Decode檢測支持的格式型,然後通過flag命令行標誌參數選擇輸出的格式。
**练习 10.1** 展jpeg程序以支持任意像格式之的相互转换使用image.Decode检测支持的格式型,然后通过flag命令行标志参数选择输出的格式。
**練習 10.2** 設計一個通用的壓縮文件取框架,用來讀取ZIParchive/zip和POSIX tararchive/tar格式壓縮的文。使用似上面的註冊技術來擴展支持不同的壓縮格式,然後根據需要通匿名導入選擇導入要支持的壓縮格式的驅動包。
**练习 10.2** 设计一个通用的压缩文件取框架,用来读取ZIParchive/zip和POSIX tararchive/tar格式压缩的文。使用似上面的注册技术来扩展支持不同的压缩格式,然后根据需要通匿名导入选择导入要支持的压缩格式的驱动包。

View File

@@ -1,22 +1,22 @@
## 10.6. 包和命名
在本中,我們將提供一些關於Go語言獨特的包和成命名的定。
在本中,我们将提供一些关于Go语言独特的包和成命名的定。
當創建一包,一般要用短小的包名,但也不能太短導致難以理解。標準庫中最常用的包有bufio、bytes、flag、fmt、http、io、json、os、sort、sync和time等包。
当创建一包,一般要用短小的包名,但也不能太短导致难以理解。标准库中最常用的包有bufio、bytes、flag、fmt、http、io、json、os、sort、sync和time等包。
的名字都簡潔明了。例如,不要將一個類似imageutil或ioutilis的通用包命名util然它看起很短小。要量避免包名使用可能被常用局部量的名字,這樣可能致用重命名入包例如前面看到的path包。
的名字都简洁明了。例如,不要将一个类似imageutil或ioutilis的通用包命名util然它看起很短小。要量避免包名使用可能被常用局部量的名字,这样可能致用重命名入包例如前面看到的path包。
包名一般采用單數的形式。標準庫的bytes、errors和strings使用了複數形式,這是爲了避免和預定義的類型衝突,同樣還有go/types是了避免和type關鍵字衝突。
包名一般采用单数的形式。标准库的bytes、errors和strings使用了复数形式,这是为了避免和预定义的类型冲突,同样还有go/types是了避免和type关键字冲突。
要避免包名有其它的含。例如2.5中我們的溫度轉換包最初使用了temp包名雖然併沒有持多久。但是一糟糕的嚐試,因temp乎是臨時變量的同義詞。然後我們有一段時間使用了temperature作包名,然名字併沒有表包的眞實用途。最後我們改成了和strconv標準包類似的tempconv包名這個名字比之前的就好多了。
要避免包名有其它的含。例如2.5中我们的温度转换包最初使用了temp包名虽然并没有持多久。但是一糟糕的尝试,因temp乎是临时变量的同义词。然后我们有一段时间使用了temperature作包名,然名字并没有表包的真实用途。最后我们改成了和strconv标准包类似的tempconv包名这个名字比之前的就好多了。
現在讓我們看看如何命名包的成。由是通包的入名字引入包里面的成例如fmt.Println包含了包名和成名信息。因此,我一般不需要關註Println的具體內容,因fmt包名已包含了這個信息。當設計一個包的候,需要考包名和成員名兩個部分如何很好地配合。下面有一些例子:
现在让我们看看如何命名包的成。由是通包的入名字引入包里面的成例如fmt.Println包含了包名和成名信息。因此,我一般不需要关注Println的具体内容,因fmt包名已包含了这个信息。当设计一个包的候,需要考包名和成员名两个部分如何很好地配合。下面有一些例子:
```
bytes.Equal flag.Int http.Get json.Marshal
```
可以看到一些常用的命名模式。strings包提供了和字符串相關的諸多操作:
可以看到一些常用的命名模式。strings包提供了和字符串相关的诸多操作:
```Go
package strings
@@ -30,9 +30,9 @@ type Reader struct{ /* ... */ }
func NewReader(s string) *Reader
```
字符串string本身併沒有出在每個成員名字中。因爲用戶會這樣引用些成strings.Index、strings.Replacer等。
字符串string本身并没有出在每个成员名字中。因为用户会这样引用些成strings.Index、strings.Replacer等。
其它一些包,可能描述了一的數據類例如html/template和math/rand等暴露一主要的數據結構和與它相的方法,有一以New命名的函數用於創建實例。
其它一些包,可能描述了一的数据类例如html/template和math/rand等暴露一主要的数据结构和与它相的方法,有一以New命名的函数用于创建实例。
```Go
package rand // "math/rand"
@@ -41,6 +41,6 @@ type Rand struct{ /* ... */ }
func New(source Source) *Rand
```
可能致一些名字重例如template.Template或rand.Rand就是爲什麽這些種類的包名往往特别短的原因之一。
可能致一些名字重例如template.Template或rand.Rand就是为什么这些种类的包名往往特别短的原因之一。
在另一個極端,有像net/http包那含有非常多的名字和種類不多的數據類型,因爲它們都是要行一個複雜的複合任務。盡管有近二十種類型和更多的函,但是包中最重要的成名字卻是簡單明了的Get、Post、Handle、Error、Client、Server等。
在另一个极端,有像net/http包那含有非常多的名字和种类不多的数据类型,因为它们都是要行一个复杂的复合任务。尽管有近二十种类型和更多的函,但是包中最重要的成名字却是简单明了的Get、Post、Handle、Error、Client、Server等。

View File

@@ -1,13 +1,13 @@
### 10.7.1. 工作區結構
### 10.7.1. 工作区结构
對於大多的Go言用戶,隻需要配置一名叫GOPATH的環境變量,用指定前工作目録卽可。需要切到不同工作區的時候,要更新GOPATH就可以了。例如們在編寫本書時將GOPATH設置爲`$HOME/gobook`
对于大多的Go言用户,只需要配置一名叫GOPATH的环境变量,用指定前工作目录即可。需要切到不同工作区的时候,要更新GOPATH就可以了。例如们在编写本书时将GOPATH设置为`$HOME/gobook`
```
$ export GOPATH=$HOME/gobook
$ go get gopl.io/...
```
你用前面介的命令下載本書全部的例子源碼之後,你的前工作的目録結構應該是這樣的:
你用前面介的命令下载本书全部的例子源码之后,你的前工作的目录结构应该是这样的:
```
GOPATH/
@@ -34,11 +34,11 @@ GOPATH/
...
```
GOPATH對應的工作區目録有三子目。其中src子目録用於存儲源代。每包被保存在$GOPATH/src的相對路徑爲包導入路的子目例如gopl.io/ch1/helloworld相對應的路徑目録。我看到,一GOPATH工作的src目中可能有多個獨立的版本控製繫統例如gopl.io和golang.org分别對應不同的Git倉庫。其中pkg子目録用於保存編譯後的包的目文件bin子目録用於保存編譯後的可行程序例如helloworld可行程序。
GOPATH对应的工作区目录有三子目。其中src子目录用于存储源代。每包被保存在$GOPATH/src的相对路径为包导入路的子目例如gopl.io/ch1/helloworld相对应的路径目录。我看到,一GOPATH工作的src目中可能有多个独立的版本控制系统例如gopl.io和golang.org分别对应不同的Git仓库。其中pkg子目录用于保存编译后的包的目文件bin子目录用于保存编译后的可行程序例如helloworld可行程序。
第二個環境變量GOROOT用指定Go的安裝目録,還有它自帶的標準庫包的位置。GOROOT的目録結構和GOPATH因此存放fmt包的源代碼對應目録應該爲$GOROOT/src/fmt。用一般不需要置GOROOT認情況下Go言安工具會將其設置爲安裝的目録路徑
第二个环境变量GOROOT用指定Go的安装目录,还有它自带的标准库包的位置。GOROOT的目录结构和GOPATH因此存放fmt包的源代码对应目录应该为$GOROOT/src/fmt。用一般不需要置GOROOT认情况下Go言安工具会将其设置为安装的目录路径
其中`go env`命令用於査看Go音工具涉及的所有環境變量的值,包括未設置環境變量的默值。GOOS環境變量用指定目操作繫統例如android、linux、darwin或windowsGOARCH環境變量用指定理器的例如amd64、386或arm等。然GOPATH環境變量是唯一必需要置的,但是其它環境變量也會偶爾用到。
其中`go env`命令用于查看Go音工具涉及的所有环境变量的值,包括未设置环境变量的默值。GOOS环境变量用指定目操作系统例如android、linux、darwin或windowsGOARCH环境变量用指定理器的例如amd64、386或arm等。然GOPATH环境变量是唯一必需要置的,但是其它环境变量也会偶尔用到。
```
$ go env

View File

@@ -1,10 +1,10 @@
### 10.7.2. 下
### 10.7.2. 下
使用Go言工具箱的go命令可以根據包導入路找到本地工作的包,甚至可以從互聯網上找到和更新包。
使用Go言工具箱的go命令可以根据包导入路找到本地工作的包,甚至可以从互联网上找到和更新包。
使用命令`go get`可以下載一個單一的包或者用`...`載整個子目里面的每包。Go言工具箱的go命令同時計算併下載所依的每包,也是前一例子中golang.org/x/net/html自動出現在本地工作區目録的原因。
使用命令`go get`可以下载一个单一的包或者用`...`载整个子目里面的每包。Go言工具箱的go命令同时计算并下载所依的每包,也是前一例子中golang.org/x/net/html自动出现在本地工作区目录的原因。
一旦`go get`命令下了包,然就是安包或包對應的可行的程序。我們將在下一節再關註它的細節,現在隻是展示整個下載過程是如何的簡單。第一命令是取golint工具它用於檢測Go源代碼的編程風格是否有問題。第二命令是用golint命令2.6.2的gopl.io/ch2/popcount包代碼進行編碼風格檢査。它友好地告了忘了包的文
一旦`go get`命令下了包,然就是安包或包对应的可行的程序。我们将在下一节再关注它的细节,现在只是展示整个下载过程是如何的简单。第一命令是取golint工具它用于检测Go源代码的编程风格是否有问题。第二命令是用golint命令2.6.2的gopl.io/ch2/popcount包代码进行编码风格检查。它友好地告了忘了包的文
```
$ go get github.com/golang/lint/golint
@@ -13,9 +13,9 @@ src/gopl.io/ch2/popcount/main.go:1:1:
package comment should be of the form "Package popcount ..."
```
`go get`命令支持前流行的託管網站GitHub、Bitbucket和Launchpad可以直接向它的版本控製繫統請求代碼。對於其它的站,你可能需要指定版本控製繫統的具體路徑和協議,例如 Git或Mercurial。`go help importpath`取相的信息。
`go get`命令支持前流行的托管网站GitHub、Bitbucket和Launchpad可以直接向它的版本控制系统请求代码。对于其它的站,你可能需要指定版本控制系统的具体路径和协议,例如 Git或Mercurial。`go help importpath`取相的信息。
`go get`命令取的代碼是眞實的本地存儲倉庫,而不僅僅隻是複製源文件,因此你依然可以使用版本管理工具比本地代碼的變更或者切到其它的版本。例如golang.org/x/net包目録對應一個Git倉庫
`go get`命令取的代码是真实的本地存储仓库,而不仅仅只是复制源文件,因此你依然可以使用版本管理工具比本地代码的变更或者切到其它的版本。例如golang.org/x/net包目录对应一个Git仓库
```
$ cd $GOPATH/src/golang.org/x/net
@@ -24,7 +24,7 @@ origin https://go.googlesource.com/net (fetch)
origin https://go.googlesource.com/net (push)
```
需要意的是入路含有的站域名和本地Git倉庫對應遠程服地址不相同,眞實的Git地址是go.googlesource.com。這其實是Go言工具的一特性,可以包用一自定義的導入路,但是眞實的代碼卻是由更通用的服提供例如googlesource.com或github.com。因爲頁面 https://golang.org/x/net/html 包含了如下的元數據,它告Go言的工具前包眞實的Git倉庫託管地址:
需要意的是入路含有的站域名和本地Git仓库对应远程服地址不相同,真实的Git地址是go.googlesource.com。这其实是Go言工具的一特性,可以包用一自定义的导入路,但是真实的代码却是由更通用的服提供例如googlesource.com或github.com。因为页面 https://golang.org/x/net/html 包含了如下的元数据,它告Go言的工具前包真实的Git仓库托管地址:
```
$ go build gopl.io/ch1/fetch
@@ -33,8 +33,8 @@ $ ./fetch https://golang.org/x/net/html | grep go-import
content="golang.org/x/net git https://go.googlesource.com/net">
```
如果指定`-u`命令行標誌參數`go get`命令將確保所有的包和依的包的版本都是最新的,然重新編譯和安裝它們。如果不包含該標誌參數的話,而且如果包已在本地存在,那麽代碼那麽將不會被自更新。
如果指定`-u`命令行标志参数`go get`命令将确保所有的包和依的包的版本都是最新的,然重新编译和安装它们。如果不包含该标志参数的话,而且如果包已在本地存在,那么代码那么将不会被自更新。
`go get -u`命令隻是簡單地保證每個包是最新版本,如果是第一次下載包則是比很方便的;但是對於發布程序可能是不合的,因本地程序可能需要對依賴的包做精的版本依管理。通常的解方案是使用vendor的目録用於存儲依賴包的固定版本的源代碼,對本地依的包的版本更新也是慎和持可控的。在Go1.5之前,一般需要改包的入路,所以複製後golang.org/x/net/html入路可能會變爲gopl.io/vendor/golang.org/x/net/html。最新的Go言命令已支持vendor特性但限篇幅這里併不討論vendor的具體細節。不可以通`go help gopath`命令看Vendor的助文
`go get -u`命令只是简单地保证每个包是最新版本,如果是第一次下载包则是比很方便的;但是对于发布程序可能是不合的,因本地程序可能需要对依赖的包做精的版本依管理。通常的解方案是使用vendor的目录用于存储依赖包的固定版本的源代码,对本地依的包的版本更新也是慎和持可控的。在Go1.5之前,一般需要改包的入路,所以复制后golang.org/x/net/html入路可能会变为gopl.io/vendor/golang.org/x/net/html。最新的Go言命令已支持vendor特性但限篇幅这里并不讨论vendor的具体细节。不可以通`go help gopath`命令看Vendor的助文
**練習 10.3:** http://gopl.io/ch1/helloworld?go-get=1 獲取內容,看本的代碼的眞實託管的址(`go get`求HTML頁面時包含了`go-get`參數,以别普通的瀏覽器請求)。
**练习 10.3:** http://gopl.io/ch1/helloworld?go-get=1 获取内容,看本的代码的真实托管的址(`go get`求HTML页面时包含了`go-get`参数,以别普通的浏览器请求)。

View File

@@ -1,10 +1,10 @@
### 10.7.3. 建包
### 10.7.3. 建包
`go build`命令編譯命令行參數指定的每包。如果包是一個庫,則忽略輸出結果;可以用於檢測包的可以正確編譯的。如果包的名字是main`go build`將調用連接器在前目録創建一個可執行程序;以入路的最一段作爲可執行程序的名字。
`go build`命令编译命令行参数指定的每包。如果包是一个库,则忽略输出结果;可以用于检测包的可以正确编译的。如果包的名字是main`go build`将调用连接器在前目录创建一个可执行程序;以入路的最一段作为可执行程序的名字。
爲每個目録隻包含一包,因此每個對應可執行程序或者叫Unix術語中的命令的包,要求放到一個獨立的目中。些目録有時候會放在名叫cmd目的子目下面,例如用提供Go文檔服務的golang.org/x/tools/cmd/godoc命令就是放在cmd子目§10.7.4)。
为每个目录只包含一包,因此每个对应可执行程序或者叫Unix术语中的命令的包,要求放到一个独立的目中。些目录有时候会放在名叫cmd目的子目下面,例如用提供Go文档服务的golang.org/x/tools/cmd/godoc命令就是放在cmd子目§10.7.4)。
包可以由它們的導入路指定,就像前面看到的那,或者用一個相對目録的路知指定,相對路徑必須`.``..`開頭。如果有指定參數,那麽默認指定爲當前目録對應的包。 下面的命令用於構建同一包, 然它們的寫法各不相同:
包可以由它们的导入路指定,就像前面看到的那,或者用一个相对目录的路知指定,相对路径必须`.``..`开头。如果有指定参数,那么默认指定为当前目录对应的包。 下面的命令用于构建同一包, 然它们的写法各不相同:
```
$ cd $GOPATH/src/gopl.io/ch1/helloworld
@@ -25,7 +25,7 @@ $ cd $GOPATH
$ go build ./src/gopl.io/ch1/helloworld
```
但不能這樣
但不能这样
```
$ cd $GOPATH
@@ -33,7 +33,7 @@ $ go build src/gopl.io/ch1/helloworld
Error: cannot find package "src/gopl.io/ch1/helloworld".
```
也可以指定包的源文件列表,一般這隻用於構建一些小程序或做一些臨時性的實驗。如果是main包將會以第一Go源文件的基文件名作爲最終的可行程序的名字。
也可以指定包的源文件列表,一般这只用于构建一些小程序或做一些临时性的实验。如果是main包将会以第一Go源文件的基文件名作为最终的可行程序的名字。
```
$ cat quoteargs.go
@@ -52,22 +52,22 @@ $ ./quoteargs one "two three" four\ five
["one" "two three" "four five"]
```
特别是對於這類一次性行的程序,我希望快的構建併運行它。`go run`命令實際上是合了建和行的兩個步驟
特别是对于这类一次性行的程序,我希望快的构建并运行它。`go run`命令实际上是合了建和行的两个步骤
```
$ go run quoteargs.go one "two three" four\ five
["one" "two three" "four five"]
```
第一行的參數列表中,第一不是以`.go`尾的將作爲可執行程序的參數運行。
第一行的参数列表中,第一不是以`.go`尾的将作为可执行程序的参数运行。
認情況下,`go build`命令建指定的包和它依的包,然後丟棄除了最的可行文件之外所有的中間編譯結果。依分析和編譯過程雖然都是很快的,但是隨着項目增加到幾十個包和成韆上萬行代,依賴關繫分析和編譯時間的消耗將變的可,有候可能需要幾秒種,卽使這些依賴項沒有改
认情况下,`go build`命令建指定的包和它依的包,然后丢弃除了最的可行文件之外所有的中间编译结果。依分析和编译过程虽然都是很快的,但是随着项目增加到几十个包和成千上万行代,依赖关系分析和编译时间的消耗将变的可,有候可能需要几秒种,即使这些依赖项没有改
`go install`命令和`go build`命令很相似,但是它保存每包的編譯成果,而不是將它們都丟棄。被編譯的包被保存到$GOPATH/pkg目下,目録路徑和 src目録路徑對應,可行程序被保存到$GOPATH/bin目。(很多用戶會將$GOPATH/bin添加到可行程序的索列表中。)有,`go install`命令和`go build`命令都不重新編譯沒有發生變化的包,可以使後續構建更快捷。了方便編譯依賴的包,`go build -i`命令將安裝每個目標所依的包。
`go install`命令和`go build`命令很相似,但是它保存每包的编译成果,而不是将它们都丢弃。被编译的包被保存到$GOPATH/pkg目下,目录路径和 src目录路径对应,可行程序被保存到$GOPATH/bin目。(很多用户会将$GOPATH/bin添加到可行程序的索列表中。)有,`go install`命令和`go build`命令都不重新编译没有发生变化的包,可以使后续构建更快捷。了方便编译依赖的包,`go build -i`命令将安装每个目标所依的包。
爲編譯對應不同的操作繫統平台和CPU架`go install`命令會將編譯結果安到GOOS和GOARCH對應的目。例如在Mac繫統golang.org/x/net/html包被安到$GOPATH/pkg/darwin_amd64目下的golang.org/x/net/html.a文件。
为编译对应不同的操作系统平台和CPU架`go install`命令会将编译结果安到GOOS和GOARCH对应的目。例如在Mac系统golang.org/x/net/html包被安到$GOPATH/pkg/darwin_amd64目下的golang.org/x/net/html.a文件。
針對不同操作繫統或CPU的交叉建也是很簡單的。需要置好目標對應的GOOS和GOARCH後運行構建命令可。下面交叉編譯的程序將輸出它在編譯時操作繫統和CPU型:
针对不同操作系统或CPU的交叉建也是很简单的。需要置好目标对应的GOOS和GOARCH后运行构建命令可。下面交叉编译的程序将输出它在编译时操作系统和CPU型:
<u><i>gopl.io/ch10/cross</i></u>
```Go
@@ -76,7 +76,7 @@ func main() {
}
```
下面以64位和32位境分别行程序:
下面以64位和32位境分别行程序:
```
$ go build gopl.io/ch10/cross
@@ -87,19 +87,19 @@ $ ./cross
darwin 386
```
有些包可能需要針對不同平台和理器型使用不同版本的代文件,以便於處理底的可移植性問題或提供一些特定代提供化。如果一文件名包含了一操作繫統或處理器型名字例如net_linux.go或asm_amd64.sGo言的建工具將隻在對應的平台編譯這些文件。有一特别的構建註釋註釋可以提供更多的構建過程控。例如,文件中可能包含下面的註釋
有些包可能需要针对不同平台和理器型使用不同版本的代文件,以便于处理底的可移植性问题或提供一些特定代提供化。如果一文件名包含了一操作系统或处理器型名字例如net_linux.go或asm_amd64.sGo言的建工具将只在对应的平台编译这些文件。有一特别的构建注释注释可以提供更多的构建过程控。例如,文件中可能包含下面的注释
```Go
// +build linux darwin
```
在包明和包註釋的前面,該構建註釋參數告訴`go build`隻在編譯程序對應的目操作繫統是Linux或Mac OS X時才編譯這個文件。下面的構建註釋則表示不編譯這個文件:
在包明和包注释的前面,该构建注释参数告诉`go build`只在编译程序对应的目操作系统是Linux或Mac OS X时才编译这个文件。下面的构建注释则表示不编译这个文件:
```Go
// +build ignore
```
更多細節,可以考go/build包的構建約束部分的文
更多细节,可以考go/build包的构建约束部分的文
```
$ go doc go/build

View File

@@ -1,8 +1,8 @@
### 10.7.4. 包文
### 10.7.4. 包文
Go言的編碼風格鼓勵爲每個包提供良好的文。包中每個導出的成和包明前都應該包含目的和用法明的註釋
Go言的编码风格鼓励为每个包提供良好的文。包中每个导出的成和包明前都应该包含目的和用法明的注释
Go言中包文檔註釋一般是完整的句子,第一行是包的摘要明,註釋後僅跟着包聲明語句。註釋中函數的參數或其它的標識符併不需要外的引或其它標記註明。例如下面是fmt.Fprintf的文檔註釋
Go言中包文档注释一般是完整的句子,第一行是包的摘要明,注释后仅跟着包声明语句。注释中函数的参数或其它的标识符并不需要外的引或其它标记注明。例如下面是fmt.Fprintf的文档注释
```Go
// Fprintf formats according to a format specifier and writes to w.
@@ -10,13 +10,13 @@ Go語言中包文檔註釋一般是完整的句子第一行是包的摘要説
func Fprintf(w io.Writer, format string, a ...interface{}) (int, error)
```
Fprintf函格式化的細節在fmt包文中描述。如果註釋後僅跟着包聲明語句,那註釋對應整個包的文。包文檔對應的註釋隻能有一個(譯註:其可以有多,它們會組合成一包文檔註釋),包註釋可以出在任何一源文件中。如果包的註釋內容比較長,一般放到一個獨立的源文件中fmt包註釋就有300行之多。這個專門用於保存包文的源文件通常叫doc.go。
Fprintf函格式化的细节在fmt包文中描述。如果注释后仅跟着包声明语句,那注释对应整个包的文。包文档对应的注释只能有一个(译注:其可以有多,它们会组合成一包文档注释),包注释可以出在任何一源文件中。如果包的注释内容比较长,一般放到一个独立的源文件中fmt包注释就有300行之多。这个专门用于保存包文的源文件通常叫doc.go。
好的文檔併不需要面面俱到,文本身應該是簡潔但可不忽略的。事Go言的格更喜歡簡潔的文檔,併且文也是需要像代碼一樣維護的。對於一組聲明語句,可以用一個精鍊的句子描述,如果是而易的功能則併不需要註釋
好的文档并不需要面面俱到,文本身应该是简洁但可不忽略的。事Go言的格更喜欢简洁的文档,并且文也是需要像代码一样维护的。对于一组声明语句,可以用一个精炼的句子描述,如果是而易的功能则并不需要注释
在本中,要空間允許,我之前很多包明都包含了註釋文檔,但你可以從標準庫中發現很多更好的例子。有兩個工具可以到你。
在本中,要空间允许,我之前很多包明都包含了注释文档,但你可以从标准库中发现很多更好的例子。有两个工具可以到你。
首先是`go doc`命令,命令打印包的明和每個成員的文檔註釋,下面是整包的文
首先是`go doc`命令,命令打印包的明和每个成员的文档注释,下面是整包的文
```
$ go doc time
@@ -34,7 +34,7 @@ type Time struct { ... }
...many more...
```
或者是某個具體包成員的註釋文檔
或者是某个具体包成员的注释文档
```
$ go doc time.Since
@@ -44,7 +44,7 @@ func Since(t Time) Duration
It is shorthand for time.Now().Sub(t).
```
或者是某個具體包的一方法的註釋文檔
或者是某个具体包的一方法的注释文档
```
$ go doc time.Duration.Seconds
@@ -53,7 +53,7 @@ func (d Duration) Seconds() float64
Seconds returns the duration as a floating-point number of seconds.
```
命令不需要入完整的包入路或正的大小。下面的命令打印encoding/json包的`(*json.Decoder).Decode`方法的文
命令不需要入完整的包入路或正的大小。下面的命令打印encoding/json包的`(*json.Decoder).Decode`方法的文
```
$ go doc json.decode
@@ -63,12 +63,12 @@ func (dec *Decoder) Decode(v interface{}) error
it in the value pointed to by v.
```
第二工具名字也叫godoc它提供可以相互交叉引用的HTML面,但是包含和`go doc`命令相同以及更多的信息。10.1演示了time包的文11.6節將看到godoc演示可以交互的示例程序。godoc的在線服務 https://godoc.org ,包含了成韆上萬的開源包的索工具。
第二工具名字也叫godoc它提供可以相互交叉引用的HTML面,但是包含和`go doc`命令相同以及更多的信息。10.1演示了time包的文11.6节将看到godoc演示可以交互的示例程序。godoc的在线服务 https://godoc.org ,包含了成千上万的开源包的索工具。
你也可以在自己的工作區目録運行godoc服務。運行下面的命令,然後在瀏覽器査看 http://localhost:8000/pkg 面:
你也可以在自己的工作区目录运行godoc服务。运行下面的命令,然后在浏览器查看 http://localhost:8000/pkg 面:
```
$ godoc -http :8000
```
其中`-analysis=type``-analysis=pointer`命令行標誌參數用於打開文檔和代碼中關於靜態分析的果。
其中`-analysis=type``-analysis=pointer`命令行标志参数用于打开文档和代码中关于静态分析的果。

View File

@@ -1,12 +1,12 @@
### 10.7.5. 部包
### 10.7.5. 部包
在Go音程序中,包的封裝機製是一重要的特性。沒有導出的標識符隻在同一個包內部可以訪問,而出的標識符則是面向全宇宙都是可的。
在Go音程序中,包的封装机制是一重要的特性。没有导出的标识符只在同一个包内部可以访问,而出的标识符则是面向全宇宙都是可的。
候,一個中間的狀態可能也是有用的,對於一小部分信任的包是可的,但不是所有調用者都可。例如,當我們計劃將一個大的包拆分很多小的更容易維護的子包,但是我們併不想將內部的子包結構也完全暴露出去。同,我可能希望在部子包之共享一些通用的理包,或者我們隻是想實驗一個新包的還併不穩定的接口,暫時隻暴露一些受限的用使用。
候,一个中间的状态可能也是有用的,对于一小部分信任的包是可的,但不是所有用者都可。例如,当我们计划将一个大的包拆分很多小的更容易维护的子包,但是我们并不想将内部的子包结构也完全暴露出去。同,我可能希望在部子包之共享一些通用的理包,或者我们只是想实验一个新包的还并不稳定的接口,暂时只暴露一些受限的用使用。
![](../images/ch10-01.png)
爲了滿足這些需求Go言的建工具包含internal名字的路段的包入路做了特殊理。這種包叫internal包internal包能被和internal目有同一父目的包所入。例如net/http/internal/chunked部包能被net/http/httputil或net/http包但是不能被net/url包入。不net/url包可以入net/http/httputil包。
为了满足这些需求Go言的建工具包含internal名字的路段的包入路做了特殊理。这种包叫internal包internal包能被和internal目有同一父目的包所入。例如net/http/internal/chunked部包能被net/http/httputil或net/http包但是不能被net/url包入。不net/url包可以入net/http/httputil包。
```
net/http

View File

@@ -1,13 +1,13 @@
### 10.7.6. 査詢
### 10.7.6. 查询
`go list`命令可以査詢可用包的信息。其最簡單的形式,可以測試包是否在工作區併打印它的入路
`go list`命令可以查询可用包的信息。其最简单的形式,可以测试包是否在工作区并打印它的入路
```
$ go list github.com/go-sql-driver/mysql
github.com/go-sql-driver/mysql
```
`go list`命令的參數還可以用`"..."`表示匹配任意的包的入路。我可以用它列表工作中的所有包:
`go list`命令的参数还可以用`"..."`表示匹配任意的包的入路。我可以用它列表工作中的所有包:
```
$ go list ...
@@ -20,7 +20,7 @@ cmd/api
...many more...
```
或者是特定子目下的所有包:
或者是特定子目下的所有包:
```
$ go list gopl.io/ch3/...
@@ -33,7 +33,7 @@ gopl.io/ch3/printints
gopl.io/ch3/surface
```
或者是和某個主題相關的所有包:
或者是和某个主题相关的所有包:
```
$ go list ...xml...
@@ -41,7 +41,7 @@ encoding/xml
gopl.io/ch7/xmlselect
```
`go list`命令可以取每包完整的元信息,而不僅僅隻是導入路徑,這些元信息可以以不同格式提供給用戶。其中`-json`命令行參數表示用JSON格式打印每包的元信息。
`go list`命令可以取每包完整的元信息,而不仅仅只是导入路径,这些元信息可以以不同格式提供给用户。其中`-json`命令行参数表示用JSON格式打印每包的元信息。
```
$ go list -json hash
@@ -71,7 +71,7 @@ $ go list -json hash
}
```
命令行參數`-f`則允許用戶使用text/template包§4.6)的模闆語言定義輸出文本的格式。下面的命令打印strconv包的依的包,然用join模闆函數將結果鏈接爲一行,連接時每個結果之用一空格分隔:
命令行参数`-f`则允许用户使用text/template包§4.6)的模板语言定义输出文本的格式。下面的命令打印strconv包的依的包,然用join模板函数将结果链接为一行,连接时每个结果之用一空格分隔:
{% raw %}
```
@@ -80,7 +80,7 @@ errors math runtime unicode/utf8 unsafe
```
{% endraw %}
譯註上面的命令在Windows的命令行運行會遇到`template: main:1: unclosed action`錯誤。産生這個錯誤的原因是因命令行命令中的`" "`參數進行了轉義處理。可以按照下面的方法解決轉義字符串的問題
译注上面的命令在Windows的命令行运行会遇到`template: main:1: unclosed action`错误。产生这个错误的原因是因命令行命令中的`" "`参数进行了转义处理。可以按照下面的方法解决转义字符串的问题
{% raw %}
```
@@ -88,7 +88,7 @@ $ go list -f "{{join .Deps \" \"}}" strconv
```
{% endraw %}
下面的命令打印compress子目下所有包的依包列表:
下面的命令打印compress子目下所有包的依包列表:
{% raw %}
```
@@ -101,7 +101,7 @@ compress/zlib -> bufio compress/flate errors fmt hash hash/adler32 io
```
{% endraw %}
譯註Windows下有同樣有問題,要避免轉義字符串的榦擾
译注Windows下有同样有问题,要避免转义字符串的干扰
{% raw %}
```
@@ -109,8 +109,8 @@ $ go list -f "{{.ImportPath}} -> {{join .Imports \" \"}}" compress/...
```
{% endraw %}
`go list`命令對於一次性的交互式査詢或自動化構建或測試腳本都很有助。我們將在11.2.4中再次使用它。每子命令的更多信息,包括可置的字段和意,可以用`go help list`命令看。
`go list`命令对于一次性的交互式查询或自动化构建或测试脚本都很有助。我们将在11.2.4中再次使用它。每子命令的更多信息,包括可置的字段和意,可以用`go help list`命令看。
在本章,我們解釋了Go言工具中除了測試命令之外的所有重要的子命令。在下一章,我們將看到如何用`go test`命令去行Go言程序中的測試代碼
在本章,我们解释了Go言工具中除了测试命令之外的所有重要的子命令。在下一章,我们将看到如何用`go test`命令去行Go言程序中的测试代码
**練習 10.4** 建一工具,根命令行指定的參數,報告工作所有依指定包的其它包集合。提示:你需要`go list`命令次,一次用初始化包,一次用所有包。你可能需要用encoding/json§4.5)包分析出的JSON格式的信息。
**练习 10.4** 建一工具,根命令行指定的参数,报告工作所有依指定包的其它包集合。提示:你需要`go list`命令次,一次用初始化包,一次用所有包。你可能需要用encoding/json§4.5)包分析出的JSON格式的信息。

View File

@@ -1,10 +1,10 @@
## 10.7. 工具
本章剩下的部分將討論Go言工具箱的具功能,包括如何下、格式化、建、測試和安Go語言編寫的程序。
本章剩下的部分将讨论Go言工具箱的具功能,包括如何下、格式化、建、测试和安Go语言编写的程序。
Go言的工具箱集合了一列的功能的命令集。它可以看作是一包管理器(類似於Linux中的apt和rpm工具包的査詢、計算的包依賴關繫、從遠程版本控製繫統和下載它們等任。它也是一個構建繫統,計算文件的依賴關繫,然後調用編譯器、滙編器和接器建程序,然它故意被設計成沒有標準的make命令那麽複雜。它也是一個單元測試和基準測試的驅動程序,我們將在第11章討論測試話題
Go言的工具箱集合了一列的功能的命令集。它可以看作是一包管理器(类似于Linux中的apt和rpm工具包的查询、计算的包依赖关系、从远程版本控制系统和下载它们等任。它也是一个构建系统,计算文件的依赖关系,然后调用编译器、汇编器和接器建程序,然它故意被设计成没有标准的make命令那么复杂。它也是一个单元测试和基准测试的驱动程序,我们将在第11章讨论测试话题
Go言工具箱的命令有着似“瑞士刀”的格,着一打子的子命令,有一些我們經常用到例如get、run、build和fmt等。你可以行go或go help命令査看內置的助文檔,爲了査詢方便,我列出了最常用的命令:
Go言工具箱的命令有着似“瑞士刀”的格,着一打子的子命令,有一些我们经常用到例如get、run、build和fmt等。你可以行go或go help命令查看内置的助文档,为了查询方便,我列出了最常用的命令:
```
$ go
@@ -26,7 +26,7 @@ Use "go help [command]" for more information about a command.
...
```
爲了達到零配置的設計目標Go言的工具箱很多地方都依賴各種約定。例如,根據給定的源文件的名Go言的工具可以找到源文件對應的包,因爲每個目録隻包含了一的包,且到的入路和工作的目録結構是對應的。定一包的入路Go言的工具可以找到對應的目録中沒個實體對應的源文件。它可以根據導入路找到存儲代碼倉庫的遠程服器的URL。
为了达到零配置的设计目标Go言的工具箱很多地方都依赖各种约定。例如,根据给定的源文件的名Go言的工具可以找到源文件对应的包,因为每个目录只包含了一的包,且到的入路和工作的目录结构是对应的。定一包的入路Go言的工具可以找到对应的目录中没个实体对应的源文件。它可以根据导入路找到存储代码仓库的远程服器的URL。
{% include "./ch10-07-1.md" %}

View File

@@ -1,7 +1,7 @@
# 第十章 包和工具
現在隨便一小程序的實現都可能包含超10000個函數。然而作者一般需要考其中很小的一部分和做很少的設計,因爲絶大部分代都是由他人編寫的,它們通過類似包或模的方式被重用。
现在随便一小程序的实现都可能包含超10000个函数。然而作者一般需要考其中很小的一部分和做很少的设计,因为绝大部分代都是由他人编写的,它们通过类似包或模的方式被重用。
Go言有超100個的標準包(譯註:可以用`go list std | wc -l`命令査看標準包的具體數目),標準庫爲大多的程序提供了必要的基礎構件。在Go的社,有很多成熟的包被設計、共享、重用和改,目前互聯網上已經發布了非常多的Go語音開源包,它可以通 http://godoc.org 索。在本章,我們將演示如果使用已有的包和建新的包。
Go言有超100个的标准包(译注:可以用`go list std | wc -l`命令查看标准包的具体数目),标准库为大多的程序提供了必要的基础构件。在Go的社,有很多成熟的包被设计、共享、重用和改,目前互联网上已经发布了非常多的Go语音开源包,它可以通 http://godoc.org 索。在本章,我们将演示如果使用已有的包和建新的包。
Go還自帶了工具箱,里面有很多用來簡化工作和包管理的小工具。在本書開始的候,我們已經見識過如何使用工具箱自的工具來下載、構件和行我的演示程序了。在本章,我們將看看些工具的基本設計理論和嚐試更多的功能,例如打印工作中包的文檔和査詢相關的元數據等。在下一章,我們將探討探索包的單元測試用法。
Go还自带了工具箱,里面有很多用来简化工作和包管理的小工具。在本书开始的候,我们已经见识过如何使用工具箱自的工具来下载、构件和行我的演示程序了。在本章,我们将看看些工具的基本设计理论和尝试更多的功能,例如打印工作中包的文档和查询相关的元数据等。在下一章,我们将探讨探索包的单元测试用法。