變量的定義
var a =1//編譯器會推斷變量 a的類型為int
b :=1 //短變量聲明
var c int篓吁;c=1// 變量聲明,并且賦值
變量的重聲明
短變量聲明蚪拦。通過使用它杖剪,我們可以對同一個代碼塊中的變量進行重聲明。
例子:
var err error
n, err := io.WriteString(os.Stdout, "Hello\n")//使用短變量聲明對新變量n和舊變量err進行了“聲明并賦值”驰贷,這也是對后者的重聲明
變量重聲明的前提條件
- 由于變量的類型在其初始化時就已經(jīng)確定了盛嘿,所以對它再次聲明時賦予的類型必須與其原本
的類型相同,否則會產(chǎn)生編譯錯誤括袒。 - 變量的重聲明只可能發(fā)生在某一個代碼塊中次兆。如果與當前的變量重名的是外層代碼塊中的變
量,那么就是可重名變量了锹锰。 - 變量的重聲明只有在使用短變量聲明時才會發(fā)生芥炭,否則也無法通過編譯。如果要在此處聲明
全新的變量恃慧,那么就應該使用包含關(guān)鍵字var的聲明語句园蝠,但是這時就不能與同一個代碼塊
中的任何變量有重名了 。 - 被“聲明并賦值”的變量必須是多個痢士,并且其中至少有一個是新的變量垛孔。這時我們才可以說
對其中的舊變量進行了重聲明俊抵。
可重名變量
例子:
package main
import (
"fmt"
)
var str = "我在main外面"
func main() {
var str = "我在main里面"
{
str := "我在代碼塊內(nèi)"
fmt.Println(str)
}
fmt.Println(str)
}
//輸出的結(jié)果
//我在代碼塊內(nèi)
//我在main里面
變量的查找:
首先,代碼引用變量的時候總會最優(yōu)先查找當前代碼塊中的那個變量。注意骤素,這里的“當前
代碼塊”僅僅是引用變量的代碼所在的那個代碼塊烦却,并不包含任何子代碼塊酗捌。其次妈橄,如果當前代碼塊中沒有聲明以此為名的變量,那么程序會沿著代碼塊的嵌套關(guān)系赞庶,從
直接包含當前代碼塊的那個代碼塊開始训挡,一層一層地查找。一般情況下歧强,程序會一直查到當前代碼包代表的那層代碼塊澜薄。如果仍然找不到,那么 Go 語
言的編譯器就會報錯了摊册。如果我們把代碼包導入語句寫成import . XXX的形式肤京,那么就會讓這個“XXX”包中公開的程序?qū)嶓w被當前源碼文件中的代碼,視為當前代碼包中的程序?qū)嶓w。在查找當前源碼文件不存在后忘分,會查用這種方式導入的代碼包
重名變量與變量重聲明中的變量區(qū)別
-
變量重聲明中的變量一定是在某一個代碼塊內(nèi)的棋枕。注意,這里的“某一個代碼塊內(nèi)”并不包
含它的任何子代碼塊妒峦,否則就變成了“多個代碼塊之間”重斑。而重名變量指的正是在多個代
碼塊之間的由相同的標識符代表的變量。 -
變量重聲明是對同一個變量的多次聲明肯骇,這里的變量只有一個窥浪。而重名變量中涉及的變量
肯定是有多個的。 - 不論對變量重聲明多少次笛丙,其類型必須始終一致漾脂,具體遵從它第一次被聲明時給定的類型。
而重名變量之間不存在類似的限制胚鸯,它們的類型可以是任意的骨稿。 - 如果重名變量所在的代碼塊之間存在直接或間接的嵌套關(guān)系,那么它們之間一定會存
在“屏蔽”的現(xiàn)象姜钳。但是這種現(xiàn)象絕對不會在變量重聲明的場景下出現(xiàn)坦冠。
判斷變量的類型
語法:
/*
類型斷言表達式的語法形式是x.(T)。其中的x代表要被判斷類型的那個值傲须。這
個值當下的類型必須是接口類型的
*/
container := []string{"111", "222"}
// 需要將 container 轉(zhuǎn)成接口類型,才可以使用類型推斷(如果不是接口趟脂,那類型推斷又有什么必要了)
value, ok := interface{}(container).([]string
/*
ok:將代表類型判斷的結(jié)果bool類型
value:
ok=true:被判斷的值將會被自動轉(zhuǎn)換為[]string類型的值泰讽,并賦給變量value
ok=false:value將被賦予nil
*/