当前位置: 首页 > 面试题库 >

解组到接口{}中,然后执行类型声明

林弘文
2023-03-14
问题内容

string通过Rabbitmq消息系统获得了。在发送之前,

我使用json.Marshal,将结果转换为string并通过Rabbitmq发送。

我转换和发送的结构可以是:(更改了结构的名称和大小,但这没有关系)

type Somthing1 struct{
   Thing        string    `json:"thing"`
   OtherThing   int64     `json:"other_thing"`
}

要么

type Somthing2 struct{
   Croc        int       `json:"croc"`
   Odile       bool      `json:"odile"`
}

消息完全像a一样经过,string并打印在另一面(某些服务器)

到目前为止,一切正常。现在,我试图将它们转换回它们的结构并声明类型。

第一次尝试是通过:

func typeAssert(msg string) {

 var input interface{}

 json.Unmarshal([]byte(msg), &input)

 switch input.(type){
 case Somthing1:
    job := Somthing1{}
    job = input.(Somthing1)
    queueResults(job)

  case Somthing2:
    stats := Somthing2{}
    stats = input.(Somthing2)
    queueStatsRes(stats)
 default:
}

这是行不通的。当input在拆封后打印它的类型时,我得到map[string]interface{}(?!?)

甚至比这更奇怪,映射键是我得到的字符串,映射值是空的。

我做了其他一些尝试,例如:

 func typeAssert(msg string) {

  var input interface{}

  json.Unmarshal([]byte(msg), &input)

  switch v := input.(type){
  case Somthing1:
    v = input.(Somthing1)
    queueResults(v)

   case Somthing2:
    v = input.(Somthing2)
    queueStatsRes(v)
  default:
}

并且还尝试编写此答案中解释的开关:
Golang:无法在非接口值上键入switch

switch v := interface{}(input).(type)

仍然没有成功…

有任何想法吗?


问题答案:

功能文档json中显示了包解组到的默认类型Unmarshal

bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null

由于您要编组为interface{},因此返回的类型将仅来自该集合。该json软件包不了解Something1Something2。您需要从将map[string]interface{}json对象解组为的转换,或者直接解组为所需的struct类型。

如果您不想从通用接口中解压缩数据,或者以某种方式标记数据以便知道期望的类型,则可以迭代地获取json并尝试将其解编为所需的每种类型。

您甚至可以将它们打包到包装结构中,为您进行拆封:

type Something1 struct {
    Thing      string `json:"thing"`
    OtherThing int64  `json:"other_thing"`
}

type Something2 struct {
    Croc  int  `json:"croc"`
    Odile bool `json:"odile"`
}

type Unpacker struct {
    Data       interface{}
}

func (u *Unpacker) UnmarshalJSON(b []byte) error {
    smth1 := &Something1{}
    err := json.Unmarshal(b, smth1)

    // no error, but we also need to make sure we unmarshaled something
    if err == nil && smth1.Thing != "" {
        u.Data = smth1
        return nil
    }

    // abort if we have an error other than the wrong type
    if _, ok := err.(*json.UnmarshalTypeError); err != nil && !ok {
        return err
    }

    smth2 := &Something2{}
    err = json.Unmarshal(b, smth2)
    if err != nil {
        return err
    }

    u.Data = smth2
    return nil
}

http://play.golang.org/p/Trwd6IShDW



 类似资料:
  • 问题内容: 我有一些代码已经被转储并实际上被卡住了-之前我已经使用过RPC和JSON方面的东西,但是当它在本地运行良好时,我似乎无法使其在RPC上正常工作。 (也在这里,但没有可用的TCP!http: //play.golang.org/p/HmK-K09D2J ) 输出令人惊讶,因为它表明编组而不是实际数据出了点问题- 在Wireshark中运行它,我可以看到数据以正确的格式发送(我在另一个问题

  • 问题内容: 一般情况下,我无法优雅地获取图像像素作为数组。 现在,功能getPixels如下所示: 但是我认为这很丑。Golang知道图像的类型,我希望这样: 我也不能坚持。也许有一种方法可以从接口获取类型? 问题答案: 通过使用如下所示的类型开关,可以简化大型结构: 您仍然必须列出所有可能的类型,但这更好。 由于所有图像实现都是具有名为的字段的结构指针,因此您可以使用反射来获取该字段。此实现将处

  • 问题内容: 在正确掌握接口最佳实践的过程中,我注意到一些声明,例如: 代替 -据我所知,原因是因为它有一定的灵活性,以防万一你不想实现ArrayList,但又可能实现另一种类型的列表。 通过这种逻辑,我建立了一个示例: 我的问题是,我无法访问batheSelf()方法,因为它仅适用于Cat。这使我相信,仅在使用接口中声明的方法时才应从接口声明(而不是子类中的其他方法),否则应直接从类中声明(在本例

  • 我对打字稿有点陌生,让我有点困惑的一件事是类型/接口声明。我正在编写一个库,它目前有几个类和更多的类型/接口声明。我在大多数代码中使用这些类型/接口,最初我会将它们放在 types 文件夹中的单个文件中,然后我会将它们导入到需要的任何位置,现在我在 文件夹中有一个声明命名空间类型的 ,在这个中我导出我在整个代码中使用的所有类型/接口。这种方法可以吗,或者是否有更好的方法来组织类型和接口定义?

  • 问题内容: 我想组成另一种类型的类型,但用假冒替换字段之一(这是接口值)。我遇到的问题是正在使用基础字段,因此我似乎无法覆盖该字段。 我在这里演示了这个问题:https : //play.golang.org/p/lHGnyjzIS-Y 为什么打印?我要打印。 谢谢。 问题答案: 通过,您正在调用 提升的 方法,方法接收者将是哪种类型,并调用何处是哪种类型,这就是它打印的原因。 在Go中有嵌入,但

  • 问题内容: 当使用as函数参数类型,给定非指针类型并与之一起使用时,我在Go中遇到了一个错误。 因为一段代码值得一千个单词,所以下面是一个示例: 哪个输出: 把我的结构变成一个… 稍后再读一些内容,可以解释其中的一部分,它本身就是一种类型,而不是某种无类型的容器,它解释了,以及无法获取初始类型并返回。的事实。 从文档: 要将JSON解组为接口值,Unmarshal将其中之一存储在接口值中:[…]