mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2024-11-16 19:33:47 +00:00
71 lines
3.5 KiB
Markdown
71 lines
3.5 KiB
Markdown
## 2.6. 包和文件
|
||
|
||
Go語言中的包和其他語言的庫或模塊概唸類似, 目的都是爲了支持模塊好, 封裝, 單獨編譯和代碼重用. 一個包的源代碼保存在一個或多個以.爲後綴名的文件中, 通常一個包所在目録路徑的後綴是包的導入路徑; 例如包 gopl.io/ch1/helloworld 對應的目録路徑是 $GOPATH/src/gopl.io/ch1/helloworld.
|
||
|
||
每個包作爲一個獨立的名字空間. 例如, 在 image 包中的 Decode 函數 和 unicode/utf16 包中的 Decode 函數是不同的. 要在外部包引用該函數, 必鬚顯式使用 image.Decode 或 utf16.Decode 訪問.
|
||
|
||
包可以讓我們通過控製那些名字是外部可見的來隱藏信息. 在Go中, 一個簡單的規則是: 如果一個名字是大寫字母開頭的, 那麽該名字是導齣的.
|
||
|
||
爲了演示基本的用法, 假設我們的溫度轉換軟件已經很流行, 我們希望到Go社區也能使用這個包. 我們該如何做呢?
|
||
|
||
讓我們創建一個名爲 gopl.io/ch2/tempconv 的包, 是前面例子的一個改進版本. (我們約定我們的例子都是以章節順序來編號的, 這樣的路徑更容易閱讀.) 包代碼存儲在兩個文件, 用來演示如何在一個文件聲明然後在其他的文件訪問; 在現實中, 這樣小的包一般值需要一個文件.
|
||
|
||
我們把變量的聲明, 對應的常量, 還有方法都放到 tempconv.go 文件:
|
||
|
||
```Go
|
||
gopl.io/ch2/tempconv
|
||
// Package tempconv performs Celsius and Fahrenheit conversions.
|
||
package tempconv
|
||
|
||
import "fmt"
|
||
|
||
type Celsius float64
|
||
type Fahrenheit float64
|
||
|
||
const (
|
||
AbsoluteZeroC Celsius = -273.15
|
||
FreezingC Celsius = 0
|
||
BoilingC Celsius = 100
|
||
)
|
||
|
||
func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) }
|
||
func (f Fahrenheit) String() string { return fmt.Sprintf("%g°F", f) }
|
||
```
|
||
|
||
轉換函數放在 conv.go 文件中:
|
||
|
||
```Go
|
||
package tempconv
|
||
|
||
// CToF converts a Celsius temperature to Fahrenheit.
|
||
func CToF(c Celsius) Fahrenheit { return Fahrenheit(c*9/5 + 32) }
|
||
|
||
// FToC converts a Fahrenheit temperature to Celsius.
|
||
func FToC(f Fahrenheit) Celsius { return Celsius((f - 32) * 5 / 9) }
|
||
```
|
||
|
||
每個文件都是以包的聲明語句開始, 用來指定包的名字. 當包被導入的時候, 包內部的成員將通過類似 tempconv.CToF 的方式訪問. 包級別的名字, 例如在一個文件聲明的類型和常量, 在同一個包的其他文件也是可以直接訪問的,
|
||
就好像所有代碼都在一個文件一樣. 要註意的是 tempconv.go 文件導入了 fmt 包, 但是 conv.go 文件並沒有, 因爲它並沒有用到 fmt 包.
|
||
|
||
因爲包級別的常量名都是以大寫字母開頭, 它們也是可以像 tempconv.AbsoluteZeroC 這樣被訪問的:
|
||
|
||
```Go
|
||
fmt.Printf("Brrrr! %v\n", tempconv.AbsoluteZeroC) // "Brrrr! -273.15°C"
|
||
```
|
||
|
||
要將 攝氏溫度轉換爲 華氏溫度, 需要先導入 gopl.io/ch2/tempconv, 然後就可以使用下面的代碼轉換了:
|
||
|
||
```Go
|
||
fmt.Println(tempconv.CToF(tempconv.BoilingC)) // "212°F"
|
||
```
|
||
|
||
在每個文件的包聲明前僅跟着的註釋是包註釋(§10.7.4). 通常, 第一句應該先是包的功能概要.
|
||
一個包通常隻有一個文件有包註釋. 如果包註釋很大, 通常會放到一個獨立的 doc.go 文件中.
|
||
|
||
**練習 2.1:** 向 tempconv 包 添加類型, 常量和函數用來處理 Kelvin 絕對溫度的轉換,
|
||
Kelvin 絕對零度是 −273.15°C, Kelvin 絕對溫度1K和攝氏度1°C的單位間隔是一樣的.
|
||
|
||
{% include "./ch2-06-1.md" %}
|
||
|
||
{% include "./ch2-06-2.md" %}
|