我试图创建一个工厂方法,该方法为实现某些接口的结构返回构造函数。
这是一些示例代码,用于说明我正在使用的模式。
// 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
当我尝试访问结构中未在接口中定义的字段时,出现错误:
f.Name undefined (type Foo has no field or method Name)
我相信问题是我的构造函数
func NewRealFoo(name string) Foo
具有接口作为返回类型,而不是*RealFoo
。但是为了将其用作工厂方法的FooConstructor
类型,返回类型必须是Foo
接口。如何修复我的代码,以便可以访问
f.Name
字段? 最佳答案
您实际上是在返回RealFoo
对象,但作为Foo
的实现。
要获取RealFoo
结构的字段,请使用类型断言:
f.(RealFoo).Name
或者,如果不是
RealFoo
,则避免发生恐慌: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
}
如果您愿意修改工厂构造函数,也可以从
RealFoo
返回NewRealFoo
,而不是Foo
。因为它实现了该接口,所以在期望使用Foo
的任何地方使用它仍然是有效的。这就是在函数NewRealFoo
中返回RealFoo
时在Foo
中所做的事情。func NewRealFoo(name string) RealFoo {
return &RealFoo{Name: name}
}