我有多种类型:
// Using GridLayoutManager
recyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
// Using StaggeredGridLayoutManager
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(numberOfColumns, StaggeredGridLayoutManager.VERTICAL));
它们都有两个共同的属性,type QueryMessage struct {
Header MessageHeader
Type MessageType
Query SqlQuery
}
type UpdateMessage struct {
Header MessageHeader
Type MessageType
OldData map[string]interface{}
NewData map[string]interface{}
}
type InsertMessage struct {
Header MessageHeader
Type MessageType
Data map[string]interface{}
}
和Header
。最后,我需要将它们聚合成一组通用消息。
目前我的Type
界面如下所示:
Message
所以我基本上做的就是这样(将它们全部转换为Message接口):
type Message interface {}
这样做有效,但它丢失了所有类型信息,我希望仍然可以从q := QueryMessage{ ... }
u := UpdateMessage{ ... }
i := InsertMessage{ ... }
allMessages := [3]Message { Message(q), Message(u), Message(i), }
类型中公开Header
和Type
(这样客户端代码理论上可以投射Message
基于Message
返回原始类型。
如何做到这一点?我无法找到正确的方法,界面不具备属性,如果我使Type
成为结构,Go不允许我施放e。 G。一个Message
到QueryMessage
。
答案 0 :(得分:4)
您的界面可以提供访问者:
type Message interface {
GetHeader() MessageHeader
GetType() MessageType
}
然后,您必须在所有类型上实现此接口。
要分解公共部分,您可以使用额外的基本类型,并将其嵌入到其他结构中:
// the interface :
type Message interface {
GetHeader() MessageHeader
GetType() MessageType
}
// a base struct type, which holds 2 fields and implements the Message interface :
type baseMessage struct {
Header MessageHeader
Type MessageType
}
func (b *baseMessage) GetHeader() MessageHeader {
return b.Header
}
func (b *baseMessage) GetType() MessageType {
return b.Type
}
// your three types, with an embedded "baseMessage" part :
type QueryMessage struct {
baseMessage
Query SqlQuery
}
type UpdateMessage struct {
baseMessage
OldData map[string]interface{}
NewData map[string]interface{}
}
type InsertMessage struct {
baseMessage
Data map[string]interface{}
}
// compile time check : all the above types implement the Message interface :
var _ Message = &QueryMessage{}
var _ Message = &UpdateMessage{}
var _ Message = &InsertMessage{}
答案 1 :(得分:0)
只是一个意见,但考虑到Header
和Type
只是字段/数据而不是方法/行为,我丢失了消息interface
而是使用消息struct
。
type Message struct {
Header MessageHeader
Type MessageType
Details interface{}
}
然后根据Type
字段的值,您可以将Details
投射到任何内容。
if m.Type == QueryMessageType {
q := m.Details.(SqlQuery)
} else if m.Type == UpdateMessageType {
u := m.Details.(UpdateMessageDetails)
}
或者只使用类型开关
switch m.Details.(type) {
case SqlQuery:
// ...
case UpdateMessageDetails:
// ...
}