## 8.2\. 語法
Go中變量的聲明語法和C++相反。定義變量時,先寫變量的名字,然后是變量的類型。這樣 不會出現像C++中, 類型不能匹配后面所有變量的情況(指針類型)。而且語法清晰,便于 閱讀。
```
Go C++
var v1 int // int v1;
var v2 string // const std::string v2; (approximately 近似等價)
var v3 [10]int // int v3[10];
var v4 []int // int* v4; (approximately 近似等價)
var v5 struct { f int } // struct { int f; } v5;
var v6 *int // int* v6; (but no pointer arithmetic 沒有指針算術)
var v7 map[string]int // unordered_map<string, int>* v7; (approximately 近似等價)
var v8 func(a int) int // int (*v8)(int a);
```
變量的聲明通常是從某些關鍵字開始,例如var, func,const或type。對于類型的專有方法定義, 在變量名前面還要加上對應該方法發類型對象變量,細節清參考discussion of interfaces。
你也可以在關鍵字后面加括號,這樣可以同時定義多個變量。
```
var (
i int
m float
)
```
When declaring a function, you must either provide a name for each parameter or not provide a name for any parameter; you can't omit some names and provide others. You may group several names with the same type:
定義函數的時候,你可以指定每個參數的名字或者不指定任何參數名字,但是你不能只指定部分函數參數的 名字。如果是相鄰的參數是相同的類型,也可以統一指定類型。
```
func f(i, j, k int, s, t string)
```
對于變量,可以在定時進行初始化。對于這種情況,我們可以省略變量的類型部分,因為Go編譯器 可以根據初始化的值推導出變量的類型。
```
var v = *p
```
如果變量定義時沒有初始化,則必須指定類型。沒有顯式初始化的變量,會被自動初始化為空的值, 例如0,nil等。Go不存在完全未初始化的變量。
用:=操作符,還有更簡短的定義語法:
```
v1 := v2
```
和下面語句等價:
```
var v1 = v2
```
Go還提供多個變量同時賦值:
```
i, j = j, i // Swap i and j.
```
函數也可以返回多個值,多個返回值需要用括號括起來。返回值可以用一個等于符號賦給 多個變量。
```
func f() (i int, j int) { ... }
v1, v2 = f()
```
Go中使用很少的分號,雖然每個語句之間實際上是用分號分割的。因為,go編譯器會在看似 完整的語句末尾自動添加分號(具體細節清參考Go語言手冊)。 當然,自動添加分號也可能帶來一些問題。例如:
```
func g()
{ // INVALID
}
```
在g()函數后面會被自動添加分號,導致函數編譯出錯。下面的代碼也有類似的 問題:
```
if x {
}
else { // INVALID
}
```
在第一個花括號}的后面會被自動添加分號,導致else語句 出現語法錯誤。
分號可以用來分割語句,你仍然可以安裝C++的方式來使用分號。不過Go語言中,常常省略不 必要的分號。 只有在 循環語句的初始化部分,或者一行寫多個語句的時候才是必須的。
繼續前面的問題。我們并不用擔心因為花括號的位置導致的編譯錯誤,因此我們可以用 gofmt 來排版程序代碼。 gofmt 工具總是可以將代碼排版成統一的風格。While the style may initially seem odd, it is as good as any other style, and familiarity will lead to comfort.
當用指針訪問結構體的時候,我們用.代替->語法。 因此,用結構體類型和結構體指針類型訪問結構體成員的語法是一樣的。
```
type myStruct struct { i int }
var v9 myStruct // v9 has structure type
var p9 *myStruct // p9 is a pointer to a structure
f(v9.i, p9.i)
```
Go不要求在if語句的條件部分用小括弧,但是要求if后面的代碼 部分必須有花括弧。類似的規則也適用于for和switch等語句。
```
if a < b { f() } // Valid
if (a < b) { f() } // Valid (condition is a parenthesized expression)
if (a < b) f() // INVALID
for i = 0; i < 10; i++ {} // Valid
for (i = 0; i < 10; i++) {} // INVALID
```
Go語言中沒有while和do/while循環語句。我們可以用只有一個 條件語句的for來代替while循環。如果省略for 的條件部分,則是一個無限循環。
Go增加了帶標號的break 和continue語法。不過標號必須 是針對for,switch或select代碼段的。
對于switch語句,case匹配后不會再繼續匹配后續的部分。 對于沒有任何匹配的情況,可以用fallthrough 語句。
```
switch i {
case 0: // empty case body
case 1:
f() // f is not called when i == 0!
}
```
case語句還可以帶多個值:
```
switch i {
case 0, 1:
f() // f is called if i == 0 || i == 1.
}
```
case語句不一定必須是整數或整數常量。如果省略switch的 要匹配的值,那么case可以是任意的條件語言。
```
switch {
case i < 0:
f1()
case i == 0:
f2()
case i > 0:
f3()
}
```
++ 和 -- 不再是表達式,它們只能在語句中使用。因此, c = *p++ 是錯誤的。語句 *p++ 的含義也完全不同,在go中等價于 (*p)++ 。
defer可以用于指定函數返回前要執行的語句。
```
fd := open("filename")
defer close(fd) // fd will be closed when this function returns.
```
- 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. 相關資源