翻譯自:
什麼是變參函式?
變參函式是指可以接受可變數量的引數的函式。
語法如果函式的最後乙個引數表示為...t
,則該函式可以接受任意數量t
型別引數。
注意
:必須是引數列表的最後乙個引數才可以指定為可變引數。
通過示例來理解可變函式如何工作
func
(slice [
]type, elems ...type)
type
讓我們建立自己的變參函式。我們將編寫乙個簡單的程式來查詢引數列表中是否存在某個整數,如果存在,就列印其所在的索引位置:
package main
import
("fmt"
)func
find
(num int
, nums ...
int)}if
!found
fmt.
printf
("\n")}
func
main()
在上面的程式中,func find(num int, nums ...int)
接受任意數量的引數。在find
函式中引數nums
的型別為整型切片。
變參函式的工作原理是把可變引數轉換為可變引數型別的新切片。例如,在上面程式中的第22
行,find
函式中的可變引數是89
,90
,95
。find
函式接受乙個int
型別的可變引數。因此這三個引數被編譯器轉換為乙個int
型別切片int
然後被傳入find
函式。
在第10
行,for
迴圈遍歷切片nums
,如果num
在切片中,則列印num
的位置。如果不存在,則列印未找到。
上面程式的輸出結果為:
type of nums is [
]int
89 found at index 0 in [
899095]
type of nums is [
]int
45 found at index 2 in [
5667
4590
109]
type of nums is [
]int
78 not found in [
385698]
type of nums is [
]int
87 not found in [
]
在上面程式的第25
行,find
函式只有乙個引數。我們沒有給可變引數nums ...int
傳入任何引數。這是完全合法的,在這種情況下nums
是乙個長度和容量為0
的nil
切片。
將切片作為可變引數傳遞給函式
我們已經知道可變引數在函式內部是切片。那麼可以傳遞乙個切片給可變引數嗎?讓我們將乙個切片傳遞給乙個可變引數,通過下面的例子看一下發生了什麼。
package main
import
("fmt"
)func
find
(num int
, nums ...
int)}if
!found
fmt.
printf
("\n")}
func
main()
find(89
, nums)
}
在程式的第23
行,我們將乙個切片傳遞給乙個可變引數。這是非法的,上面的程式將報錯:main.go:23: cannot use nums (type int) as type int in argument to find
。
為什麼這樣不行呢?原因很直接,find
函式的說明如下:
func
find
(num int
, nums ...
int)
根據變參函式的定義,nums ...int
意味著它將接受可變數量的int
型別引數。
在上面程式的第23
行中,將nums
作為乙個可變引數傳遞給find
函式。正如我們已經討論過的那樣,這些可變引數將轉換為int
型別的切片。在這種情況下,nums
已經是乙個int
型別切片,編譯器嘗試使用nums
建立乙個新的int
切片,像下面這樣:
find(89
,[]int
)
因為nums
是乙個int
型別 而不是int
型別。型別根本就不相同,所以會失敗。
那麼有沒有辦法將切片傳遞給變參函式?答案是肯定的。
有乙個語法糖可用於將切片傳遞給變參函式。你必須為切片新增字尾...
,這樣則可以將切片直接傳遞給函式,而不會建立新切片。
在上面的程式中,如果你將第23
行的find(89, nums)
替換為find(89, nums...)
,程式將成功編譯並有如下輸出:
type of nums is [
]int
89 found at index 0 in [
8990
95]
下面是完整的程式供您參考。
package main
import
("fmt"
)func
find
(num int
, nums ...
int)}if
!found
fmt.
printf
("\n")}
func
main()
find(89
, nums...
)}
注意事項
在變參函式中修改切片時,請確保知道自己在做什麼。
讓我們看乙個簡單的例子。
package main
import
("fmt"
)func
change
(s ...
string
)func
main()
change
(welcome...
) fmt.
println
(welcome)
}
你認為這段**將輸出什麼呢?如果你認為它輸出[go world]
。恭喜你!你已經理解了可變引數函式和切片。如果你猜錯了,沒什麼大不了,讓我來解釋下為什麼會有這樣的輸出。
在第13
行,我們使用了語法糖...
並且將切片作為可變引數傳入change
函式。
正如前面我們所討論的,如果使用了...
,welcome
切片本身會作為引數直接傳入,而不會建立新的切片。因此,welcome
將作為引數傳入change
函式。
在change
函式中,切片的第乙個元素被更改為go
,這樣程式產生了下面的輸出值
[go world]
還有另乙個例子來理解變參函式:
package main
import
("fmt"
)func
change
(s ...
string
)func
main()
change
(welcome...
) fmt.
println
(welcome)
}
上面的程式中,我們將切片welcome
作為引數傳遞給change
函式,因為切片傳遞是引用傳遞,在函式體內容對切片進行修改,在函式外部依然是改變之後的結果,但是當新元素追加到切片時,會建立乙個新陣列。將現有陣列的元素複製到此新陣列,並返回此新陣列的新切片引用。因此,在函式內部列印的s
其實新陣列的切片,在函式執行之後列印的welcome
是之前的切片,所以程式輸出如下:
[go world playground]
[go world]
Go語言學習筆記十二 Go語言切片
1 package main 23 import fmt 45 切片定義 切片是基於陣列型別的一層封裝。它非常靈活,可以自動擴容,切片是乙個引用型別 6func main else 16 b 0 100 這種寫法是錯誤的,切片必須先初始化 17var c 5 int 5 int 18 fmt.pri...
go語言學習 函式
函式宣告包括函式名,形參列表,返回值列表 可選 函式體組成 func test parameters returns 其中 parameters 就是函式的形參列表,描述了函式的引數名和引數型別,可以沒有引數但是這個括號不可以省略 returns就是返回值列表,描述了函式返回值的變數名 可選 和型別...
Golang教程 (十二)變參函式
原文 這是本golang系列教程的第十二篇。變參函式是指可以接受可變數量的引數的函式。如果乙個函式的最後乙個引數由.t表示,則表示該函式可以接受任意數量的型別為t的引數。請注意只有函式的最後乙個引數才能指定為可變引數。讓我們來建立乙個自己的變參函式。我們將編寫乙個程式來判斷某個特定整數是否包含在某個...