go語言學習 變參函式 十二

2021-08-30 15:16:20 字數 4634 閱讀 9074

翻譯自:

什麼是變參函式?

變參函式是指可以接受可變數量的引數的函式。

語法如果函式的最後乙個引數表示為...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函式中的可變引數是899095find函式接受乙個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是乙個長度和容量為0nil切片。

將切片作為可變引數傳遞給函式

我們已經知道可變引數在函式內部是切片。那麼可以傳遞乙個切片給可變引數嗎?讓我們將乙個切片傳遞給乙個可變引數,通過下面的例子看一下發生了什麼。

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的引數。請注意只有函式的最後乙個引數才能指定為可變引數。讓我們來建立乙個自己的變參函式。我們將編寫乙個程式來判斷某個特定整數是否包含在某個...