2016-10-09 61 views
0

我有一個程序使用多種類型的模塊,但所有不同類型的模塊共享某些方法。我正在嘗試構建一個可以重用於不同類型模塊的通用工廠,但是我錯過了接口繼承或Go中會調用的其他東西。Go中的接口層次

這是我試圖簡化儘可能好的一個例子:

有一個通用的工廠,使用通用Module接口:

package main 

var (
    modules []Module 
) 

type Module interface { 
    RegisterFlagSet() 
    GetName() (string) 
} 

type Factory struct { 
    instances []Module 
} 

func RegisterModules(modules []Module) { 
    modules = modules 
} 

func (f *Factory) registerFlagSets() { 
    for _,inst := range f.instances { 
    inst.RegisterFlagSet() 
    } 
} 

func (f *Factory) GetInstance(seek string)(Module) { 
    for _,inst := range f.instances { 
    if (inst.GetName() == seek) { 
     return inst 
    } 
    } 
    panic("cannot find module") 
} 

那麼,對於該模塊的更具體的實施輸入Timer。我想重新使用盡可能多的工廠儘可能:

package main 

import (
    "time" 
) 

var (
    timer_modules = []Timer{ 
    // list all the timer modules here 
    } 
) 

type Timer interface { 
    Module 
    GetTicker() (*time.Ticker) 
} 

type TimerFactory struct { 
    Factory 
} 

func NewTimerFactory() TimerFactory { 
    tfact := TimerFactory{} 
    RegisterModules(timer_modules) 
    return tfact 
} 

當我嘗試建立我得到這個錯誤:

timer_factory.go:25: cannot use timer_modules (type []Timer) as type []Module in argument to RegisterModules 

我不明白爲什麼type []Timer一個變量不能被用作type []Module,因爲接口Module的所有方法也都在接口Timer中,所以它們應該兼容或不兼容?有沒有辦法讓它們兼容?

回答

0

更改計時器

聲明
type Timer interface { 
    Module 
    GetTicker()(*time.Ticker) 
} 
+0

這似乎是有道理的,但不幸的是我仍然得到相同的'不能使用timer_modules(類型[]計時器)作爲類型[]模塊在參數RegisterModules' –

+0

它的工作,如果我只傳遞'單個實例'定時器,但它不適用於一片定時器'[] Timer'。 –

+0

更新了相應的問題 –

1

https://golang.org/doc/faq#convert_slice_of_interface給出解釋。 的解決方法之一是實現一個新的寄存器功能:

func RegisterModule(m Module) { 
    modules = append(modules, m) 
} 

,並調用該函數的範圍內的只有兩行的費用:

func NewTimerFactory() TimerFactory { 
    tfact := TimerFactory{} 
    for _, t := range timer_modules { 
    RegisterModule(t) 
    } 
    return tfact 
} 
+0

如果使用可變參數'...'運算符,該怎麼辦?所以範圍循環被刪除? –

+1

'......'表現出與切片相同的方式,並且不起作用。 –

+0

另一種方法是引入反射,這會導致性能下降和代碼複雜性。 –