如何在go中创建一个结构的一个成员的不同结构的结构?

How to create a struct with different structs of one members of struct in go?

我从服务器收到一个 json 响应,其中包含三个修复 json 对象字段和一个包含不同 json 对象的字段。

示例 - 响应 1

{
   status : "success",
   error-code : "",
   message : "login successful",
   data : {
           token : "token value",
           refresh-token : "refresh token value"
          }
}

示例 - 响应 2

{
   status : "success",
   error-code : "",
   message : "user data fetched",
   data : {
           first-name: "josh",
           last-name : "walter",
           age : "30",
           phone: 1234567890,
           address : "x street, dc"
          }
}

对于上面的 json 响应创建结构如下

type loginData struct {
    Token string `json:"token"`
    RefreshToken string `json:"refresh-token"`

}

type userdata {
    FirstName string    `json:"first-name"`
    LastName string     `json:"refresh-token"`
    Age string          `json:"age"`
    Phone string        `json:"phone"`
    Address string      `json:"address"`

}


type response struct {
    Status string       `json:"status"`
    ErrorCode string    `json:"error-code"`
    RespMessage string  `json:"message"`
    RespData string     `json:"data"`
}



如何在登录响应期间解组时添加登录数据结构,在响应结构的“RespData”字段中解组用户数据响应时如何添加用户数据结构

首先更改 RespData 字段的类型:

type response struct {
    Status      string      `json:"status"`
    ErrorCode   string      `json:"error-code"`
    RespMessage string      `json:"message"`
    RespData    interface{} `json:"data"`
}

然后,根据您提出的请求,将 RespData 字段设置为指向预期类型的​​指针的 pre-allocated 实例:

r, err := http.Get("https://some_api.com/loginData")
if err != nil {
    return err
}
defer r.Body.Close()

// check r.StatusCode and make sure it's correct

data := loginData{}
resp := response{RespData: &data}
if err := json.NewDecoder(r.Body).Decode(&resp); err != nil {
    return err
}

fmt.Println(data)

根据我的说法,您应该有两个不同的 structs 来执行此操作。一个原因是关注点分离,因为这些响应的结构将来可能会发生变化,并且这些响应来自两个不同的 API,因此最好维护不同的响应对象。

type loginData struct {
    Token        string `json:"token"`
    RefreshToken string `json:"refresh-token"`
}

type userdata struct {
    FirstName string `json:"first-name"`
    LastName  string `json:"refresh-token"`
    Age       string `json:"age"`
    Phone     string `json:"phone"`
    Address   string `json:"address"`
}

type response struct {
    Status      string `json:"status"`
    ErrorCode   string `json:"error-code"`
    RespMessage string `json:"message"`
}

type userResponse struct {
    response
    RespData userdata `json:"data"`
}

type loginResponse struct {
    response
    RespData loginData `json:"data"`
}

@mkopriva 正如你所说,尝试了这个建议,它奏效了。

package main

import (
    "encoding/json"
    "fmt"
    "strings"
)

type loginData struct {
    Token        string `json:"token"`
    RefreshToken string `json:"refresh-token"`
}

type userdata struct {
    FirstName string `json:"first-name"`
    LastName  string `json:"last-name"`
    Age       string `json:"age"`
    Phone     string `json:"phone"`
    Address   string `json:"address"`
}

type response struct {
    Status      string      `json:"status"`
    ErrorCode   string      `json:"error-code"`
    RespMessage string      `json:"message"`
    RespData    interface{} `json:"data"`
}

func main() {
    jsonresp_1 := `{
        "status" : "success",
        "error-code" : "",
        "message" : "login successful",
        "data" : {
                "token" : "token value",
                "refresh-token" : "refresh token value"
               }
     }`

    jsonresp_2 := `{
        "status" : "success",
        "error-code" : "",
        "message" : "user data fetched",
        "data" : {
                "first-name": "josh",
                "last-name" : "walter",
                "age" : "30",
                "phone": "1234567890",
                "address" : "x street, dc"
               }
     }`
    resp1 := strings.NewReader(jsonresp_1)
    data1 := loginData{}
    respdata1 := response{RespData: &data1}

    if err := json.NewDecoder(resp1).Decode(&respdata1); err != nil {
        fmt.Println(err)
    }
    fmt.Printf("token : %s \nrefreshtoken : %s \n", data1.Token, data1.RefreshToken)

    fmt.Println("-------------------")

    resp2 := strings.NewReader(jsonresp_2)
    data2 := userdata{}
    respdata2 := response{RespData: &data2}

    if err := json.NewDecoder(resp2).Decode(&respdata2); err != nil {
        fmt.Println(err)
    }
    fmt.Printf("firstname : %s \nlastname : %s ", data2.FirstName, data2.LastName)
}

输出

⚡ ⇒  go run main.go 
token : token value 
refreshtoken : refresh token value 
-------------------
firstname : josh 
lastname : walter