我正在尝试创建一个工厂方法,该方法返回一个实现某个接口(interface)的结构的构造函数。
下面是一些示例代码,说明了我正在使用的模式。
// Generic Interface
type Foo interface {
Bar() string
}
type FooConstructor func(name string) Foo
// A struct that implements Foo
type RealFoo struct {
Name string
}
func (f *RealFoo) Bar() string {
return f.Name
}
func NewRealFoo(name string) Foo {
return &RealFoo{Name: name}
}
// Factory method to return some FooConstructor
func FooFactory() FooConstructor {
// based on some logic, return some Foo constructor
return NewRealFoo
}
func main() {
ff := FooFactory()
f := ff("baz")
fmt.Println(f.Bar())
fmt.Println(f.Name)
}
http://play.golang.org/p/0RzXlIGAs8
当我尝试访问接口(interface)中未定义的结构上的字段时,出现错误:
f.Name undefined(类型 Foo 没有字段或方法名称)
我认为问题在于我的构造函数 func NewRealFoo(name string) Foo
将接口(interface)作为返回类型,而不是 *RealFoo
。但是为了将它用作工厂方法的 FooConstructor
类型,返回类型必须是 Foo
接口(interface)。
如何修复我的代码以便我可以访问字段 f.Name
?
最佳答案
您实际上返回的是 RealFoo
对象,但作为 Foo
的实现。
要获取 RealFoo
结构的字段,请使用类型断言:
f.(RealFoo).Name
或者,如果它不是 RealFoo
,为了避免 panic :
if realFoo, ok := f.(RealFoo); ok {
_ := realFoo.Name
}
或切换所有或部分可能的 Foo
switch rf := f.(type) {
case realFoo:
_ := rf.Name // rf is a realFoo
case unrealFoo:
_ := rf.ImaginaryName // rf is an unrealFoo
case surrealFoo:
_ := rf.SurrealName // rf is a surrealFoo
default:
// rf is none of the above types
}
如果您愿意修改您的工厂构造函数,您也可以从 NewRealFoo
返回一个 RealFoo
,而不是 Foo
。在需要 Foo
的任何地方使用它仍然有效,因为它实现了该接口(interface)。这就是您在 NewRealFoo
中所做的,当在返回 Foo
的函数中返回 RealFoo
时。
func NewRealFoo(name string) RealFoo {
return &RealFoo{Name: name}
}
关于Go 工厂方法返回类型接口(interface),而不是实现接口(interface)的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34954212/