2012-09-22 42 views
1

如果我有一個函數,最後一個參數是可選的,那麼使用...來允許參數是可選的,還是它被認爲是不好的形式,這是一個合適的做法嗎?可變參數是可選參數的適當解決方案嗎?

例子:

func Foo(s ...string) { 
    switch len(s) { 
     case 0: 
      fmt.Println("You didn't pass an argument") 
     case 1: 
      fallthrough 
     default: 
      fmt.Printf("You passed %s\n", s[0]) 
    } 
} 

Foo("bar")  // "You passed bar" 
Foo()    // "You didn't pass an argument" 
Foo("bar", "baz") // "You passed bar" 

在這個例子中,我不在乎太多的參數傳遞,但在需要的時候我能勝任,在default:情況。

回答

5

我不會推薦這個。 (ab)使用可變參數傳遞可選參數存在不同的問題。其中最重要的可能是最後的arg ...T)的形式只允許一種類型。對於具有多種類型的多個可選參數,可以使用...interface{},但會導致不必要的運行時間(非)裝箱成本,並且缺少任何(有用的)編譯時類型檢查。

另一個可能的反對意見是,我認爲你不會在標準庫中的任何地方找到一個示例/先例,這被認爲是一些非正式的Go編碼風格指南。

+0

關於你的第一段,我看到你在說什麼,但在我的情況下,我沒有在尋找動態類型。它的類型將是靜態的,但它包含在調用中是可選的。但是你的第二段完全符合我的想法。我會讓問題在那裏突出一段時間,但現在+1。 –

+0

你的回答和其他的都是很不錯的,但你具體處理的適當的編碼風格的問題,給標準庫作爲一個合適的標準。非常感謝。 –

0

這一切都取決於你的項目的需求,如果你的項目是在這樣的情況下,那麼就沒有任何不好的形式

可選參數工廠只爲這種情況提供。

+2

這只是它不是真正的可選參數設施。它是用來僞造可選參數的可變函數設施。副作用是編譯器無法檢查過多的參數。不知道這是否被認爲是好的形式,或者這是一種普遍接受的做法。 –

11

如果你真的需要可選參數(並且你可以從轉到STDLIB看到,這是罕見的),慣用的方法是定義與字段的結構爲每個可選參數,然後調用者可以通過一個結構字面與他們想要填寫的字段。

更常見的是提供替代函數或方法,當它只有一個或兩個「可選」參數時,應該是大部分時間。

像Python這樣的語言中的可選參數通常意味着API的增長和增長,直到函數和方法擁有比任何人都記得更多的參數,並且永遠不清楚參數的各種組合如何交互(並且測試更少)。

迫使你定義明確的函數和方法參數的各種組合需要更多的想到了你的API面前,卻使得它更實用和維護在長期。

+0

優秀點。謝謝! –