Rumah >pembangunan bahagian belakang >Golang >Golang Unmarshal dengan set tag struktur yang berbeza

Golang Unmarshal dengan set tag struktur yang berbeza

WBOY
WBOYke hadapan
2024-02-09 23:10:09566semak imbas

具有不同结构标签集的 Golang Unmarshal

editor php Baicao hari ini memperkenalkan anda kepada ciri Golang yang berkuasa - Unmarshal dengan set tag struktur yang berbeza. Dalam pengaturcaraan Golang, Unmarshal ialah proses menukar data kepada struktur. Walau bagaimanapun, apabila sumber data kami mengandungi set teg struktur yang berbeza, kaedah Unmarshal tradisional mungkin tidak memenuhi keperluan. Oleh itu, kita perlu menggunakan Golang Unmarshal dengan set tag struktur yang berbeza untuk mencapai fungsi ini. Artikel ini akan memperkenalkan secara terperinci penggunaan dan langkah berjaga-jaga bagi ciri ini. Mari kita meneroka bersama-sama!

Kandungan soalan

Saya menggunakan api alat pihak ketiga yang mempunyai nama kunci tersuai dalam jsonnya. Saya juga perlu menggunakan api pada dua persekitaran berbeza (pengeluaran dan pementasan). Malangnya, medan tersuai dalam api mempunyai nama kunci yang berbeza dalam kedua-dua persekitaran untuk mewakili data yang sama. Dalam contoh di bawah, kunci json custom-1 与暂存环境中的 json 密钥 custom-7 完全相同。我想将其中任何一个解组到相同的数据结构中,但我不知道如何进行。我希望有一种方法可以以某种方式覆盖 json.unmarshal() 函数用于在 prod 上使用 json 的标签,但在暂存时使用 jsonstaging 。对我来说,这是最有意义且最简单的解决方案。我猜我必须为我的 jsonobj 类型编写一个自定义 unmarshaljson(data []byte) error berfungsi dalam pengeluaran, tetapi sekali lagi, saya tidak tahu bagaimana untuk mencapai tingkah laku yang diingini dalam fungsi tersuai. Bolehkah sesiapa menunjukkan saya ke arah yang betul, beberapa dokumentasi atau beberapa contoh yang boleh saya gunakan?

package main

import (
    "encoding/json"
    "fmt"
)

type jsonobj struct {
    id   string `json:"custom-1" jsonstaging:"custom-7"`
    desc string `json:"custom-2" jsonstaging:"custom-8"`
}

func (i jsonobj) string() string {
    return fmt.sprintf(`{ id: "%s", desc: "%s" }`, i.id, i.desc)
}

func main() {
    var jsonprod = `{
        "custom-1": "object-a",
        "custom-2": "test"
    }
    `
    var jsonstaging = `{
        "custom-7": "object-a",
        "custom-8": "test"
    }
    `

    var jsonobjprod jsonobj
    var jsonobjstaging jsonobj

    json.unmarshal([]byte(jsonprod), &jsonobjprod)
    json.unmarshal([]byte(jsonstaging), &jsonobjstaging)

    fmt.println("production: ", jsonobjprod)
    fmt.println("staging: ", jsonobjstaging)
}

Apabila saya menjalankannya dengan go run saya mendapat

production:  { id: "object-a", desc: "test" }
staging:  { id: "", desc: "" }

Ini adalah kod semasa saya jangkakan, tetapi saya ingin mendapatkan

Production:  { Id: "object-a", Desc: "test" }
Staging:  { Id: "object-a", Desc: "test" }

Saya tidak boleh mengubah suai api persekitaran pementasan atau pengeluaran.

Saya telah cuba mencipta struktur dan antara muka yang berbeza, tetapi apabila bilangan medan (dan kekunci json tersuai) meningkat (dan ia berkembang), ia nampaknya menjadi mimpi ngeri penyelenggaraan. Tolong bantu saya jika ini adalah satu-satunya cara, saya juga tidak berjaya melakukannya sebelum saya memutuskan ini mungkin bukan jalan yang betul. .

Mula-mula, anda perlu menggunakan fungsi json.unmarshal(), tetapi isikan

dan bukannya objek yang ingin anda bina.

reflectKemudian saya menulis fungsi yang mendapat persekitaran dan peta. Ia menggelung melalui semua medan dalam contoh baharu objek sebenar (bukan peta) dan mendapat label untuk persekitaran yang anda gunakan. Ia kemudian menetapkan medan dalam objek baharu kepada

. Selepas menetapkan semua medan dengan label ia akan mengembalikan objek baharu.

map[string] 接口{}Ini kod kerja saya:

package main

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

const (
    StagingStructTag    = "jsonStaging"
    ProductionStructTag = "json"
)

type jsonObj struct {
    Id   string `json:"custom-1" jsonStaging:"custom-7"`
    Desc string `json:"custom-2" jsonStaging:"custom-8"`
}

func (i jsonObj) String() string {
    return fmt.Sprintf(`{ Id: "%s", Desc: "%s" }`, i.Id, i.Desc)
}

func main() {
    var jsonProd = `{
        "custom-1": "object-a",
        "custom-2": "test"
    }
    `
    var jsonStaging = `{
        "custom-7": "object-a",
        "custom-8": "test"
    }
    `

    var env string = "staging"
    var jsonObjProd jsonObj
    var jsonObjStaging jsonObj
    var jsonObjProdMap map[string]interface{}
    var jsonObjStagingMap map[string]interface{}

    json.Unmarshal([]byte(jsonStaging), &jsonObjStagingMap)
    json.Unmarshal([]byte(jsonProd), &jsonObjProdMap)

    jsonObjStaging = BuildJsonObj(env, jsonObjStagingMap)
    env = "production"
    jsonObjProd = BuildJsonObj(env, jsonObjProdMap)

    fmt.Println("Production: ", jsonObjProd)
    fmt.Println("Staging:    ", jsonObjStaging)
}

func BuildJsonObj(env string, objMap map[string]interface{}) jsonObj {
    var obj jsonObj
    var t reflect.Type = reflect.TypeOf(obj)
    var structTagName string

    if env == "staging" {
        structTagName = StagingStructTag

    } else if env == "production" {
        structTagName = ProductionStructTag
    }

    for i := 0; i < t.NumField(); i++ {
        var field reflect.StructField = t.Field(i)
        var tag string
        var ok bool

        if tag, ok = field.Tag.Lookup(structTagName); ok {
            switch field.Name {
            case "Id":
                obj.Id = objMap[tag].(string)
            case "Desc":
                obj.Desc = objMap[tag].(string)
            }
        }

    }
    return obj
}

Atas ialah kandungan terperinci Golang Unmarshal dengan set tag struktur yang berbeza. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam