## 5.9\. 初始化
盡管表面看來和 C 或 C++ 的初始化沒什么不同,Go 的更夠強。復雜結構可在初始化時架設,并且不同包的物件的初始化順序問題也得到正確處理。
### 5.9.1\. Constants 常量初始化
常量在 Go 里是 —— 不變的。它們在編譯時生成,即便是局部定義在函數里。它只能是數,字串或布爾。因為編譯態的限制,定義它們的表達式必須是常量表達式,可以被編譯器求值。例如,1<<3 是常量表達式, math.Sin(math.Pi/4) 不是,因為 math.Sin 的函數調用發生在運行態。
Go 的列舉常量可用 iota 生成。 因為 iota 可以是表達式的一部分,并且表達式可以隱含重復,打造一套精致的值可以變得很容易。
```
type ByteSize float64
const (
_ = iota // ignore first value by assigning to blank identifier
KB ByteSize = 1<<(10*iota)
MB
GB
TB
PB
EB
ZB
YB
)
```
給類型添加比如 String 等方法的本領,使值自動排版打印自己變得可能,即使只作為通用類型的一部分。
```
func (b ByteSize) String() string {
switch {
case b >= YB:
return fmt.Sprintf("%.2fYB", b/YB)
case b >= ZB:
return fmt.Sprintf("%.2fZB", b/ZB)
case b >= EB:
return fmt.Sprintf("%.2fEB", b/EB)
case b >= PB:
return fmt.Sprintf("%.2fPB", b/PB)
case b >= TB:
return fmt.Sprintf("%.2fTB", b/TB)
case b >= GB:
return fmt.Sprintf("%.2fGB", b/GB)
case b >= MB:
return fmt.Sprintf("%.2fMB", b/MB)
case b >= KB:
return fmt.Sprintf("%.2fKB", b/KB)
}
return fmt.Sprintf("%.2fB", b)
}
```
表達式 YB 打印 1.00YB,而 ByteSize(1e13) 打印 9.09TB
### 5.9.2\. 變量初始化
變量和常量的初始化一樣,但可以用運行態計算的普通表達式。
```
var (
HOME = os.Getenv("HOME")
USER = os.Getenv("USER")
GOROOT = os.Getenv("GOROOT")
)
```
### 5.9.3\. init函數
最后,每個源文件可以定義自身的 init() 函數來安排所需的狀態。唯一的限制是,盡管夠程可在初始化時啟動,它們只在初始完成后執行;初始化永遠是單一的執行序列。最后之后,init() 發生在包里所有變量初始化之后,而其又發生在所有的包全部導入之后。
除了初始化不能表示為聲明外,init() 函數常用來在程序運行前驗證或修補其狀態。
```
func init() {
if USER == "" {
log.Exit("$USER not set")
}
if HOME == "" {
HOME = "/usr/" + USER
}
if GOROOT == "" {
GOROOT = HOME + "/go"
}
// GOROOT may be overridden by --goroot flag on command line.
flag.StringVar(&GOROOT, "goroot", GOROOT, "Go root directory")
}
```
- 1. 關于本文
- 2. Go語言簡介
- 3. 安裝go環境
- 3.1. 簡介
- 3.2. 安裝C語言工具
- 3.3. 安裝Mercurial
- 3.4. 獲取代碼
- 3.5. 安裝Go
- 3.6. 編寫程序
- 3.7. 進一步學習
- 3.8. 更新go到新版本
- 3.9. 社區資源
- 3.10. 環境變量
- 4. Go語言入門
- 4.1. 簡介
- 4.2. Hello,世界
- 4.3. 分號(Semicolons)
- 4.4. 編譯
- 4.5. Echo
- 4.6. 類型簡介
- 4.7. 申請內存
- 4.8. 常量
- 4.9. I/O包
- 4.10. Rotting cats
- 4.11. Sorting
- 4.12. 打印輸出
- 4.13. 生成素數
- 4.14. Multiplexing
- 5. Effective Go
- 5.1. 簡介
- 5.2. 格式化
- 5.3. 注釋
- 5.4. 命名
- 5.5. 分號
- 5.6. 控制流
- 5.7. 函數
- 5.8. 數據
- 5.9. 初始化
- 5.10. 方法
- 5.11. 接口和其他類型
- 5.12. 內置
- 5.13. 并發
- 5.14. 錯誤處理
- 5.15. Web服務器
- 6. 如何編寫Go程序
- 6.1. 簡介
- 6.2. 社區資源
- 6.3. 新建一個包
- 6.4. 測試
- 6.5. 一個帶測試的演示包
- 7. Codelab: 編寫Web程序
- 7.1. 簡介
- 7.2. 開始
- 7.3. 數據結構
- 7.4. 使用http包
- 7.5. 基于http提供wiki頁面
- 7.6. 編輯頁面
- 7.7. template包
- 7.8. 處理不存在的頁面
- 7.9. 儲存頁面
- 7.10. 錯誤處理
- 7.11. 模板緩存
- 7.12. 驗證
- 7.13. 函數文本和閉包
- 7.14. 試試!
- 7.15. 其他任務
- 8. 針對C++程序員指南
- 8.1. 概念差異
- 8.2. 語法
- 8.3. 常量
- 8.4. Slices(切片)
- 8.5. 構造值對象
- 8.6. Interfaces(接口)
- 8.7. Goroutines
- 8.8. Channels(管道)
- 9. 內存模型
- 9.1. 簡介
- 9.2. Happens Before
- 9.3. 同步(Synchronization)
- 9.4. 錯誤的同步方式
- 10. 附錄
- 10.1. 命令行工具
- 10.2. 視頻和講座
- 10.3. Release History
- 10.4. Go Roadmap
- 10.5. 相關資源