mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2024-11-19 21:03:43 +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" %}
|