2015-10-13 68 views
1

我開始用簡單的界面:實現接口方法與變量參數

type Module interface { 
    Init(deps ...interface{}) error 
} 

我以爲,實施將是非常簡單的,因爲這種方法應該匹配任意數量的提供的參數。這就是我用這個代碼結束的想法,TestModule實現了Module接口。

type TestModule struct { 
} 

func (m *TestModule) Init(str string) error { 
    return nil 
} 

但是,當我想將TestModule傳遞給希望模塊的所有功能,我得到這個錯誤:

cannot use module(type *TestModule) as type Module in argument to testFunc:

func testFunc(module Module) { 

} 

編輯:有沒有實施這種行爲的任何最佳實踐?

回答

6

這沒有實現接口;

func (m *TestModule) Init(str string) error { 
    return nil 
} 

如果你產生了困惑是「因爲這種方法應該匹配任意數量的提供論據」這是一個語言功能,它可以讓呼叫者調用方法與參數個數可變(見這裏What does "..." mean when next to a parameter in a go function declaration?) 。要實現它,你需要實現相同的簽名... interface{}

所以要清楚的是,'提供的任何數量的參數'僅用於調用方法,並不意味着您可以使用任何類型的任何參數集來實現該方法,並且它將具有相同的定義。定義說明調用者傳入的實現interface{}的項目數量是可變的。

「是否有任何實施這種行爲的最佳做法?」

不是我所知道的。我認爲通常的做法是放寬傳入interface{}... interface{}的類型,然後檢查方法中的集合。例如,如果Module接口的定義爲Init(deps interface{}) error,那麼你可以像這樣在測試模塊中實現它;

func (m *TestModule) Init(deps interface{}) error { 
     str := deps.(string) 
     return nil 
} 

如果你想args來變長,你只需要添加一個for range構建到方法拆箱的價值或做一些邊界檢查。我不能說這在你的應用程序中是否會是一種好的做法,因爲我認爲這取決於你從一個單一的方法簽名中得到多少價值。它增加了額外的鍋爐板代碼,並有一些小的性能損失。

+0

我編輯了帖子。感謝您的快速回復。 – Gelidus

+0

@Gelidus我不能幫上忙,但我給了你我的兩分錢。 – evanmcdonnal