簡體   English   中英

如何在 Golang 中從 JSON 中解組一段接口

[英]How to unmarshal a slice of interfaces from JSON in Golang

我有一個variables包,其中有一個接口Variable和兩個實現接口上的方法的結構NumericalVariableTextualVariable ,就像這樣......

package variables

type Variable interface {
    GetColumnIndex() int
    IsActive() bool
    StartDataLoad()
    AddData(value string) (bool, error)
    FinishDataLoad()
    VectorLength() int
    SetVectorOffset(offset int)
    LoadIntoVector(sv string, vector []float64) float64
}

type NumericVariable struct {
    Column_idx    int
    Name          string
    Vector_offset int
    Mean          float64
    Sum           float64
    SumSq         float64
    SD            float64
    Count         float64
    Max           float64
    Min           float64
    Vector_max    float64
    Vector_min    float64
    values        []float64
    Active        bool
}

type Category struct {
    Count         int
    Vector_offset int
    Coefficient   float64
}

type TextualVariable struct {
    Column_idx    int
    Name          string
    Vector_offset int
    Categories    map[string]Category
    Categories_k  float64
    Active        bool
    Count         int
}

我有另一個模塊model ,它定義了一個Model類型,其中包括一個Variable接口,像這樣......

package model

type Model struct {
    Vars []variables.Variable
}

在我在其他地方的代碼中,我正在加載和處理數據流/文件,並根據呈現的數據創建NumericalVariableTextualVariable實例。 這些被添加到Model實例的Vars切片中

我希望能夠讀取Model結構並將其寫入 JSON 文件。

寫作很容易,我利用了 Golang 的json包中的編組(只要我對大寫的變量名感到滿意)

func (_self Model) Write(filename string) {
    file, err := json.MarshalIndent(_self, "", " ")
    if err != nil {
        log.Fatal(err)
        return
    }
    err = ioutil.WriteFile(filename, file, 0644)
    if err != nil {
        log.Fatal(err)
        return
    }
}

然而,從 JSON 中讀取被證明更棘手。 問題在於model.Vars是接口的一部分。 封送處理程序處理得很好,但是當我回讀時,我沒有關於所寫類型的信息。

我以為我可以通過反思來解決這個問題,我快到了,但我被困住了。

我的讀者長這樣...

func (_self Model) Read(filename string) {
    _model, err := ioutil.ReadFile(filename)
    if err != nil {
        log.Fatal(err)
        return
    }

    var dat map[string][]interface{}
    err = json.Unmarshal([]byte(_model), &dat)
    if err != nil {
        log.Fatal(err)
        return
    }
    _vars := dat["Vars"]
    for _, _vi := range _vars {
        k := reflect.ValueOf(_vi)
        if k.Kind() == reflect.Map {
            if len(k.MapKeys()) == 13 {
                // I know this is a numeric variable
                nv := variables.NumericVariable()
                // How do I get the reflect kind to load up nv
            }
            if len(k.MapKeys()) == 8 {
                // I know this is a textual variable
                tv := variables.TextualVariable()
                // How do I get the reflect kind to load up tv
            }
        }
    }

我可以可靠地(如果有點笨拙)檢測到反射中何時具有每種類型,但是如何讓它將值加載到結構中。 理想情況下,我希望自動解組到同名的結構變量中。 我不想一個接一個地做(雖然我可能不得不求助於那個),但我該怎么做呢?

通過將類型斷言為地圖的值,直接將您的地圖[字符串]接口{}轉換為結構


var nv NumericVariable 

for key,value:= range vars {
   nv.Column_idx = vars[key].(int) // interface{} will be converted to int
   nv.Name = vars[key].(string) // interface{} will be converted to string
   ..
   ..
   }


將 map 的接口值轉換為 struct 中給定類型的斷言類型。

暫無
暫無

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

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