Go 不改变接收器的接口
我想定义一个接口,该接口有一个方法,该方法返回一个类型为接口本身的值 我试图这样定义接口:Go 不改变接收器的接口,go,Go,我想定义一个接口,该接口有一个方法,该方法返回一个类型为接口本身的值 我试图这样定义接口: type Event interface { } type Entity interface { ApplyEvent(command Event) (Entity, error) } type Event interface { } type Entity interface { ApplyEvent(command Event) (Entity, error) } type S
type Event interface {
}
type Entity interface {
ApplyEvent(command Event) (Entity, error)
}
type Event interface {
}
type Entity interface {
ApplyEvent(command Event) (Entity, error)
}
type ShoppingList struct {
}
func (list ShoppingList) ApplyEvent(event Event) (Entity, error) {
//...
return list
}
我希望通过以下操作使结构实现实体接口:
type ShoppingList struct {
}
func (list ShoppingList) ApplyEvent(event Event) (ShoppingList, error) {
// code that changes "list" goes here.
return list, nil
}
如果这样做,然后尝试将ShoppingList传递给需要实体的函数,则会出现以下错误:
func main() {
test(ShoppingList{})
}
func test(e Entity) {
}
Cannot use 'ShoppingList{}' (type ShoppingList) as type Entity.
Type does not implement 'Entity'
need method: ApplyEvent(command Event) (Entity, error)
have method: ApplyEvent(event Event) (ShoppingList, error)
我知道我可以这样定义接口和接收器:
type Event interface {
}
type Entity interface {
ApplyEvent(command Event) error
}
type ShoppingList struct {
}
func (list *ShoppingList) ApplyEvent(event Event) error {
// code that changes "list" goes here.
return nil
}
但是我更喜欢尽可能使用纯函数和不可变的数据结构来编写代码
我想返回更改后的值,而不是改变接收器
在围棋中怎么做?看来你可能已经知道了这一点。但万一你还没想到,你也可以这样写:
type Event interface {
}
type Entity interface {
ApplyEvent(command Event) (Entity, error)
}
type Event interface {
}
type Entity interface {
ApplyEvent(command Event) (Entity, error)
}
type ShoppingList struct {
}
func (list ShoppingList) ApplyEvent(event Event) (Entity, error) {
//...
return list
}
在这里,我做的是相同的返回
,但我将其作为实体
界面而不是购物列表
返回。如果与实体
以后是一个购物列表相关,如果我想查看实体
在代码中是否是一个购物列表
,我可以尝试类型断言
但是,为
购物清单
提供一种接口方法更符合接口
的概念,因为它是一个实体,而不是消费者列举所有可能的实体。毕竟,为什么应用于“购物清单”的“事件”必然会产生另一个“购物清单”?例如,它不能生成InstacartInvoice吗?当然,在这一点上,我远远超出了你问题的范围。但是,每当接口的具体值的类型与使用者相关时,都要努力使其与该接口的方法相关。就像您在ApplyEvent
中所做的那样,您并没有真正实现该功能。接口函数的签名是:ApplyEvent(command-Event)(Entity,error)
,对于ShoppingList
它是ApplyEvent(Event-Event)(ShoppingList,error)
(它需要返回一个Entity
,不能保证是相同的具体类型。)……换句话说,补充一下其他人所说的:Go既没有“泛型”(C#-或Java风格)也没有“模板”(C++风格)。不过到了v2.0,它很可能会有泛型。Go的接口是非常真实的值,而不是某种“参数化”的抽象占位符。我强烈推荐一位Go开发者;文档有点生疏(Go不再将指针大小的值直接嵌入到接口值中),但清晰明了,切中要害。我是新手,我想我正在努力解决的问题是,如何定义一个可以在以后专门化的通用具体行为?在Java或Typescript中,您将定义一个具有泛型行为的类和应由子类实现的抽象方法。Go接口有点像一个抽象类,它定义了方法的签名,但没有定义它们。然而,相似之处到此为止。通过扩展抽象基类来组合具体类的想法更像是嵌入结构()。