前天同事提起了一個例子灌具,關(guān)于 Golang 中可變參數(shù)的使用割捅,平時使用時沒有注意這個細(xì)節(jié)恩掷,先上代碼吧碧囊。
想要實(shí)現(xiàn)的代碼邏輯很明了
1. TestArgs 接受一個 int 參數(shù)树灶,一個不定長的參數(shù),并且類型為 interface{}
2. nums 做為 slice糯而,使用 ... 語法糖打散后傳入 TestArgs
看上去邏輯沒問題天通,執(zhí)行報(bào)錯
# command-line-arguments
./test.go:13: cannot use nums (type []int64) as type []interface {} in argument to TestArgs
居然報(bào)類型不匹配,寫 Go 也一年了熄驼,這塊的認(rèn)知太不到位像寒,一直認(rèn)為會將 nums 打散,再以 interface{} 這個通用類型組成 interface{} slice 傳到 TestArgs瓜贾。
那么诺祸,我們看看到底 nums 傳進(jìn)去后是什么:
再執(zhí)行后輸出 []interface {},那么確認(rèn)是把可變參數(shù)當(dāng)做 slice 傳給函數(shù)祭芦,這點(diǎn)和 python 很像筷笨。那我們再看看 slice 是不是同一個
執(zhí)行后輸出如下
main addr of slice 0xc82000c0c0
TestArgs addr of slice 0xc82000c0c0
地址相同,原來如果傳入的可變參數(shù)本身就是由 slice 以 ... 形式傳入的龟劲,那么就直接使用這個 slice胃夏,不會新建 slice。那么我理解的 Go 的可變參數(shù)執(zhí)行方式:
對于 func(first int, arg ...T)
1. 當(dāng)不傳可變參數(shù)時咸灿,對應(yīng)的 arg 就是 nil
2. 傳入單個可變參數(shù)時构订,實(shí)際上執(zhí)行 [] T{arg1,arg2,arg3}
3. 傳入...語法糖的 slice時,直接使用這個 slice
由此我們就很好理解開篇的小例子為什么執(zhí)行不了避矢,[]int64 和 []interface{} 是兩個類型的 slice 悼瘾。