簡體   English   中英

Golang:解組地圖集

[英]Golang: Unmarshal mapset

我正在嘗試在用戶定義的結構中解組映射集,但我不斷收到此錯誤:

json: cannot unmarshal array into Go struct field A.b of type mapset.Set[int] {<nil>}

示例代碼:

package main

import (
    "encoding/json"
    "fmt"

    mapset "github.com/deckarep/golang-set/v2"
)

type A struct {
    B mapset.Set[int] `json:"b"`
}

func main() {
    a := A{mapset.NewSet(1, 2, 3)}
    r, err := json.Marshal(a)
    fmt.Println(r, err)

    var b A
    err = json.Unmarshal(r, &b)
    fmt.Println(b, err)
}

我試圖解組的不是類型結構,而是 mapset 本身,但結果是相同的。

我做錯了什么還是一些內部 package 問題?

您可以將此mapset.Set[int]類型包裝成自定義結構類型並為其編寫json.Unmarshaler實現。 我從來沒有使用過這個庫,但這里有一個例子說明你如何做到這一點,可能不是最優雅的解決方案,但它似乎工作正常(它是你問題中代碼的修改版本)。 比較也可以使用reflect.DeepEqual()集合的Equal()方法。

package main

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

    mapset "github.com/deckarep/golang-set/v2"
)

type IntSet struct {
    Values mapset.Set[int] `json:"values"`
}

func (s *IntSet) UnmarshalJSON(data []byte) error {
    // Anonymous struct for the unmarshalling purposes.
    v := struct {
        Values []int `json:"values"`
    }{}

    // Unmarshal bytes into a custom struct that
    // contains int slice as the only value.
    if err := json.Unmarshal(data, &v); err != nil {
        return err
    }

    // If there is no set inside a struct, create
    // a new set with a single '0' value.
    if s.Values == nil {
        s.Values = mapset.NewSet(0)
    }

    // Empty the set.
    s.Values.Clear()

    // Add all the values from the unmarshalled
    // bytes to the struct set.
    for _, value := range v.Values {
        s.Values.Add(value)
    }

    return nil
}

func main() {
    a := IntSet{Values: mapset.NewSet(1, 2, 3)}
    r, err := json.Marshal(a)
    fmt.Println(r, err)

    var b IntSet
    err = json.Unmarshal(r, &b)
    fmt.Println(b, err)

    // Compare a and b using [reflect.DeepEqual].
    if !reflect.DeepEqual(a, b) {
        log.Fatalln("a and b are not equal")
    }

    // Compare a and v values by using any
    // of the sets' Equal() method.
    if !a.Values.Equal(b.Values) || !b.Values.Equal(a.Values) {
        log.Fatalln("a and b values are not equal")
    }
}

此外,如果您打算將集合比較放在最終代碼中,請注意在兩個集合上使用Equal()方法比使用reflect.DeepEqual()快得多。 上面代碼塊中的第一個比較示例僅用於測試目的,您通常應避免在生產代碼中使用反射。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM