### 2.3.1. 簡短變量聲明

在函數內部，有一種稱爲簡短變量聲明語句的形式可用於聲明和初始化局部變量。它以“名字 := 表達式”形式聲明變量，變量的類型根據表達式來自動推導。下面是lissajous函數中的三個簡短變量聲明語句（§1.4）：

```Go
anim := gif.GIF{LoopCount: nframes}
freq := rand.Float64() * 3.0
t := 0.0
```

因爲簡潔和靈活的特點，簡短變量聲明被廣泛用於大部分的局部變量的聲明和初始化。var形式的聲明語句往往是用於需要顯式指定變量類型地方，或者因爲變量稍後會被重新賦值而初始值無關緊要的地方。

```Go
i := 100                  // an int
var boiling float64 = 100 // a float64
var names []string
var err error
var p Point
```

和var形式聲明變語句一樣，簡短變量聲明語句也可以用來聲明和初始化一組變量：

```Go
i, j := 0, 1
```

但是這種同時聲明多個變量的方式應該限製隻在可以提高代碼可讀性的地方使用，比如for語句的循環的初始化語句部分。

請記住“:=”是一個變量聲明語句，而“=‘是一個變量賦值操作。也不要混淆多個變量的聲明和元組的多重賦值（§2.4.1），後者是將右邊各個的表達式值賦值給左邊對應位置的各個變量：

```Go
i, j = j, i // 交換 i 和 j 的值
```

和普通var形式的變量聲明語句一樣，簡短變量聲明語句也可以用函數的返迴值來聲明和初始化變量，像下面的os.Open函數調用將返迴兩個值：

```Go
f, err := os.Open(name)
if err != nil {
	return err
}
// ...use f...
f.Close()
```

這里有一個比較微妙的地方：簡短變量聲明左邊的變量可能併不是全部都是剛剛聲明的。如果有一些已經在相同的詞法域聲明過了（§2.7），那麽簡短變量聲明語句對這些已經聲明過的變量就隻有賦值行爲了。

在下面的代碼中，第一個語句聲明了in和err兩個變量。在第二個語句隻聲明了out一個變量，然後對已經聲明的err進行了賦值操作。

```Go
in, err := os.Open(infile)
// ...
out, err := os.Create(outfile)
```

簡短變量聲明語句中必鬚至少要聲明一個新的變量，下面的代碼將不能編譯通過：

```Go
f, err := os.Open(infile)
// ...
f, err := os.Create(outfile) // compile error: no new variables
```

解決的方法是第二個簡短變量聲明語句改用普通的多重賦值語言。

簡短變量聲明語句隻有對已經在同級詞法域聲明過的變量才和賦值操作語句等價，如果變量是在外部詞法域聲明的，那麽簡短變量聲明語句將會在當前詞法域重新聲明一個新的變量。我們在本章後面將會看到類似的例子。



