GO語言————6.3 傳遞變長引數

FLy_鵬程萬里發表於2018-06-30

6.3 傳遞變長引數

如果函式的最後一個引數是採用 ...type 的形式,那麼這個函式就可以處理一個變長的引數,這個長度可以為 0,這樣的函式稱為變參函式。

func myFunc(a, b, arg ...int) {}

這個函式接受一個類似某個型別的 slice 的引數(詳見第 7 章),該引數可以通過第 5.4.4 節中提到的 for 迴圈結構迭代。

示例函式和呼叫:

func Greeting(prefix string, who ...string)
Greeting("hello:", "Joe", "Anna", "Eileen")

在 Greeting 函式中,變數 who 的值為 []string{"Joe", "Anna", "Eileen"}

如果引數被儲存在一個 slice 型別的變數 slice 中,則可以通過 slice... 的形式來傳遞引數,呼叫變參函式。

示例 6.7 varnumpar.go

package main

import "fmt"

func main() {
	x := min(1, 3, 2, 0)
	fmt.Printf("The minimum is: %d\n", x)
	slice := []int{7,9,3,5,1}
	x = min(slice...)
	fmt.Printf("The minimum in the slice is: %d", x)
}

func min(s ...int) int {
	if len(s)==0 {
		return 0
	}
	min := s[0]
	for _, v := range s {
		if v < min {
			min = v
		}
	}
	return min
}

輸出:

The minimum is: 0
The minimum in the slice is: 1

練習 6.3 varargs.go

寫一個函式,該函式接受一個變長引數並對每個元素進行換行列印。

一個接受變長引數的函式可以將這個引數作為其它函式的引數進行傳遞:

func F1(s ...string) {
	F2(s...)
	F3(s)
}

func F2(s ...string) { }
func F3(s []string) { }

變長引數可以作為對應型別的 slice 進行二次傳遞。

但是如果變長引數的型別並不是都相同的呢?使用 5 個引數來進行傳遞並不是很明智的選擇,有 2 種方案可以解決這個問題:

  1. 使用結構(詳見第 10 章):

    定義一個結構型別,假設它叫 Options,用以儲存所有可能的引數:

    type Options struct {
    	par1 type1,
    	par2 type2,
    	...
    }

    函式 F1 可以使用正常的引數 a 和 b,以及一個沒有任何初始化的 Options 結構: F1(a, b, Options {})。如果需要對選項進行初始化,則可以使用 F1(a, b, Options {par1:val1, par2:val2})

  2. 使用空介面:

    如果一個變長引數的型別沒有被指定,則可以使用預設的空介面 interface{},這樣就可以接受任何型別的引數(詳見第 11.9 節)。該方案不僅可以用於長度未知的引數,還可以用於任何不確定型別的引數。一般而言我們會使用一個 for-range 迴圈以及 switch 結構對每個引數的型別進行判斷:

    func typecheck(..,..,values … interface{}) {
    	for _, value := range values {
    		switch v := value.(type) {
    			case int: …
    			case float: …
    			case string: …
    			case bool: …
    			default: …
    		}
    	}
    }

相關文章