doumi1912 2017-04-13 09:45
浏览 51
已采纳

如何在Go中为这些类型建模

I have multiple types like this:

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{}
}

They all have two properties in common, Header and Type. In the end I need to aggregate them into an array of generic messages. At the moment my Message interface looks like this:

type Message interface {}

So what I basically do is something like this (casting them all to Message interface):

q := QueryMessage{ ... }
u := UpdateMessage{ ... }
i := InsertMessage{ ... }
allMessages := [3]Message { Message(q), Message(u), Message(i), }

This works, but it loses all the type information and I would like to be able to still expose Header and Type from the Message type (so that client code theoretically could cast the Message based on the Type back to it's original type.

How can this be done? I couldn't figure out a proper way, interfaces can't have properties and if I make Message a struct, Go doesn't allow me to cast e. g. a QueryMessage to a Message anymore.

  • 写回答

2条回答 默认 最新

  • dqpu4988 2017-04-13 10:10
    关注

    Your interface can provide accessors :

    type Message interface {
       GetHeader() MessageHeader
       GetType() MessageType
    }
    

    You then have to implement this interface on all your types.

    To factor out the common part, you can use an extra base type, and embed it in your other structs :

    // 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{}
    

    https://play.golang.org/p/Uho_2loXpZ

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 C++数组中找第二小的数字程序纠错
  • ¥50 MATLAB APP 制作出现问题
  • ¥15 wannier复现图像时berry曲率极值点与高对称点严重偏移
  • ¥15 利用决策森林为什么会出现这样·的问题(关键词-情感分析)
  • ¥15 DispatcherServlet.noHandlerFound No mapping found for HTTP request with URI[/untitled30_war_e
  • ¥15 使用deepspeed训练,发现想要训练的参数没有梯度
  • ¥15 寻找一块做为智能割草机的驱动板(标签-stm32|关键词-m3)
  • ¥15 信息管理系统的查找和排序
  • ¥15 基于STM32,电机驱动模块为L298N,四路运放电磁传感器,三轮智能小车电磁组电磁循迹(两个电机,一个万向轮),怎么用读取的电磁传感器信号表示小车所在的位置
  • ¥15 如何解决y_true和y_predict数据类型不匹配的问题(相关搜索:机器学习)