Go 可變參數 ... parameters 讀這篇就夠了
Go 語言可變參數怎麼用能最大化它的效用?本文對可變參數進行了詳細介紹。
在實際開發中,總有一些函數的參數個數是在編碼過程中無法确定的,比如我們最常用的 fmt.Printf 和 fmt.Println:
當你需要實作類似的接口時,就需要我們的可變參數出場了。
可變參數就是一個占位符,你可以将 1 個或者多個參數指派給這個占位符,這樣不管實際參數的數量是多少,都能交給可變參數來處理,我們看一下可變參數的聲明:
可變參數使用 name ...Type 的形式聲明在函數的參數清單中,而且需要是參數清單的最後一個參數,這點與其他語言類似;
可變參數在函數中将轉換為對應的 []Type 類型,是以我們可以像使用 slice 時一樣來擷取傳給函數的參數們;
有一點值得注意,golang 的可變參數不需要強制綁定參數的出現。
舉個例子,我想在 c 語言中實作一個求和任意個整數的函數 sum:
我們隻有先指定至少一個固定的形參(num)才能使用。.. 可變參數,在 golang 中是不需要這樣做的:
這也是 golang 文法簡潔的其中一個展現。
傳遞參數給帶有可變參數的函數有兩種形式,第一種與通常的參數傳遞沒有什麼差別,拿上一節的 sum 舉個例子:
除了參數的個數是動态變化的之外和普通的函數調用是一緻的。
第二種形式是使用。.. 運算符以變量。.. 的形式進行參數傳遞,這裡的變量必須是與可變參數類型相同的 slice,而不能是其他類型(沒錯,數組也不可以),看個例子:
這種形式最常用的地方是在内置函數 append 裡:
是不是和 python 的解包操作很像,沒錯,大部分情況下你可以把。.. 運算符當做是 golang 的 unpack 操作,不過有幾點不同還是要注意的:
第一,隻能對 slice 類型使用。.. 運算符:
你會見到這樣的報錯資訊:cannot use arr (type [5]int) as type []int in argument to sum
這是因為可變參數實際是個 slice,... 運算符是個文法糖,它把前面的 slice 直接複制給可變參數,而不是先解包成獨立的 n 個參數再傳遞,這也是為什麼我隻說。.. 運算符看起來像 unpack 的原因。
第二個需要注意的地方是不能把獨立傳參和 ... 運算符混用,再看個例子:
這次你會見到一個比較長的報錯:
這是和前面所說的原因是一樣的,... 運算符将不定參數直接替換成了 slice,這樣就導緻前一個獨立給出的參數不再算入可變參數的範圍内,使得函數的參數清單從 (...int) 變成了 (int, ...int),最終使得函數類型不比對編譯失敗。
正确的做法也很簡單,不要混合使用。.. 運算符給可變參數傳參即可。
讀了這篇文章,再加上一些簡單的聯系,我相信你們一定也能掌握 golang 可變參數的使用。