我想知道是否有适用的解决方案" polymorphism"在嵌入式函数中,当指向另一个时。例如,我有以下界面:
type Client interface {
Get(string) string
GetResource() string
}
和默认实现:
type ClientImpl struct {
}
func (c ClientImpl) Get(s string) string {
return fmt.Sprintf("Impl [%s]", s)
}
func (c ClientImpl) GetResource() string {
return c.Get("resource") # points to Get
}
在其他实现中(例如测试)我想用其他响应替换默认的Get函数但是保持GetResource方法不变
type TestImpl struct {
ClientImpl
}
func (t TestImpl) Get(s string) string {
return fmt.Sprintf("Test [%s]", s)
}
覆盖功能在直接调用时有效,但在从嵌入式功能调用时不起作用。查看以下测试用例生成的输出:
c := ClientImpl{}
t := TestImpl{}
fmt.Println("WORKS:")
fmt.Println("Client Get:", c.Get("aaa"))
fmt.Println("Test Get:", t.Get("aaa"))
fmt.Println("DOSN'T WORK :(")
fmt.Println("Client GetRes:", c.GetResource())
fmt.Println("Test GetRes:", t.GetResource())
# WORKS:
# Client Get: Impl [aaa]
# Test Get: Test [aaa]
# DOSN'T WORK :(
# Client GetRes: Impl [resource]
# Test GetRes: Impl [resource]
如何进行最后一次打印以输出字符串Test [resource]
?
答案 0 :(得分:2)
在您的示例中,您需要在其自己的界面中隔离Get
函数。
以下是两种类似的方法:
// one way to do this :
type Getter interface {
Get(string) string
}
type ClientImpl struct {
}
func (c ClientImpl) Get(s string) string {
return fmt.Sprintf("Impl [%s]", s)
}
type TestImpl struct {
}
func (t TestImpl) Get(s string) string {
return fmt.Sprintf("Test [%s]", s)
}
// write a bare GetResource function :
func GetResource(c Getter) string {
return c.Get("resource")
}
https://play.golang.org/p/R2XciBx_yk
// another way : store the "Getter" as a field in a struct
type Getter interface {
Get(string) string
}
type ProdGetter struct {
}
func (c ProdGetter) Get(s string) string {
return fmt.Sprintf("Impl [%s]", s)
}
type TestGetter struct {
}
func (t TestGetter) Get(s string) string {
return fmt.Sprintf("Test [%s]", s)
}
// create a struct, which holds a Getter, and has methods to do stuff with it :
type Client struct {
Getter
}
func (c *Client) GetResource() string {
return c.Get("resource")
}