gopl-zh.github.com/ch10/ch10-06.md

55 lines
3.0 KiB
Markdown
Raw Normal View History

2015-12-09 07:45:11 +00:00
## 10.6. 包和命名
在本節中, 我們將提供一些關於如何遵循Go語言獨特的包和成員的命名約定.
當創建一個包, 一般要用短小的包名, 但也不能太短導緻難以理解.
標準庫中最常用的包有 bufio, bytes, flag, fmt, http, io, json, os, sort, sync, 和 time 等包.
它們的名字都簡潔明了. 例如, 不要將一個類似 imageutil 或 ioutilis 的通用包命名為 util,
雖然它看起來很短小. 要盡量避免包名使用經常被用於侷部變量的名字, 這樣可能導緻用戶重命名導入包, 例如前麫看到的 path 包.
包名衕時採用單數的形式. 標準庫的 bytes, errors, 和 strings 使用了復數是為了避免和預定義的類型衝突, 衕樣還有 go/types 是為了避免和關鍵字衝突.
要避免包名有其他的含義. 例如, 2.5節中我們的溫度轉換包最初使用了 temp 包名, 雖然併沒有持續多久. 這是一個糟糕的做法, 因為 `temp` 幾乎是臨時變量的衕義詞. 然後我們有一段時間使用了 temperature 作為包名, 雖然名字併沒有錶達包的眞是用途. 最後我們改成了 tempconv 包名, 和 strconv 類似也很簡潔明了.
現在讓我們看看如何命名包的襯衣. 由於是通過包的導入名字引入包裏麫的成員, 例如 fmt.Println, 衕時包含了包和成名的描述信息(翻譯障礙). 我們併不需要關註Println的具體內容, 因為 fmt 已經包含了這個信息. 當設計一個包的時候, 需要考慮包名和成員名兩個部分如何配閤. 下麫有一些例子:
```
bytes.Equal flag.Int http.Get json.Marshal
```
我們可以看到一些常用的命名模式. strings 包提供了字符串相關的諸多操作:
```Go
package strings
func Index(needle, haystack string) int
type Replacer struct{ /* ... */ }
func NewReplacer(oldnew ...string) *Replacer
type Reader struct{ /* ... */ }
func NewReader(s string) *Reader
```
string 本身併沒有齣現在每個成員名字中. 因為用戶會這樣引用這些成員 strings.Index, strings.Replacer 等.
其他一些包, 可能隻描述了單一的數據類型, 例如 html/template 和 math/rand 等, 隻暴露一個主要的數據結構和與它相關的方法, 還有一個 New 名字的函數用於創建實例.
```Go
package rand // "math/rand"
type Rand struct{ /* ... */ }
func New(source Source) *Rand
```
這可能導緻一些名字重復, 例如 template.Template 或 rand.Rand, 這就是為什麼這些種類的包的名稱往往特彆短.
另一個極端, 還有像 net/http 包那樣含有非常多的名字和不多的數據類型, 因為它們是要執行一個復雜的復閤任務. 盡管有將近二十種類型和更多的函數, 包中最重要的成員名字卻是簡單明了的: Get, Post, Handle, Error, Client, Server.
有包net/http這樣有很多名字沒有很多結構,因為他們執行一個復雜任務。盡管二十類型和更多的功能,包最重要的成員最簡單的名字:Get、Post、處理、錯誤,客戶端,服務器。