亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將映射轉換為結構

將映射轉換為結構

Go
拉風的咖菲貓 2021-11-22 19:41:23
好吧,標題有點誤導。我所追求的如下:type MyStruct struct {    id   int    name string    age  int}func CreateFromMap(m map[string]interface{}) (MyStruct, error) {    var (        id   int        name string        age  int        ok   bool    )    err := errors.New("Error!")    id, ok = m["id"].(int)    if !ok {        return nil, err    }    name, ok = m["name"].(string)    if !ok {        return nil, err    }    age, ok = m["age"].(int)    if !ok {        return nil, err    }    return MyStruct{id, name, age}, nil}不要問:為什么我不使用CreateFromMap(int, string, int). 那個物體來自其他地方,不在我的控制范圍內。將映射中的每個鍵值對映射到結構體屬性已經很無聊了。但是ok在每次轉換后檢查是否一切正常是混亂的。除了反射之外,還有沒有更簡單的方法可以做到這一點?
查看完整描述

2 回答

?
繁星coding

TA貢獻1797條經驗 獲得超4個贊

假設我假設您不想使用反射,因為您不想自己做。在這種情況下,如何使用為您執行此操作的外部包?


package main


import "fmt"

import "github.com/mitchellh/mapstructure"


type MyStruct struct {

    Id   int

    Name string

    Age  int

}


func main() {

    var m = make(map[string]interface{})

    m["Id"] = 17

    m["Name"] = "foo"

    m["Age"] = 42

    fmt.Printf("%+v\n", m)


    res, err := CreateFromMap(m)

    if err != nil {

        fmt.Println(err)

        return

    }

    fmt.Printf("%+v\n", res)

}


func CreateFromMap(m map[string]interface{}) (MyStruct, error) {

    var result MyStruct

    err := mapstructure.Decode(m, &result)

    return result, err

}

輸出:


map[Age:42 Name:foo Id:17]

{Id:17 Name:foo Age:42}

無論您的結構是什么樣子,它都有優勢,但它在內部使用反射。實際上,如果不對結構的每個屬性使用反射和/或重復代碼,我看不到任何“好”的方法來做您想做的事情。但是,缺點是您必須使用大寫的屬性,以便將它們導出到外部包。


編輯(在評論中回答您的問題):

在我看來,如果要在“創建”結構時指定附加規則,應該在解碼操作之后。例如:


func CreateFromMap(m map[string]interface{}) (MyStruct, error) {

    var result MyStruct

    err := mapstructure.Decode(m, &result)

    if err != nil {

         return result, err

    }

    if result.Age <= 0 {

        result.Age = 0

    }

    if result.Name == "" {

        return result, errors.New("empty name is not allowed")

    }


    return result, err

}

這樣,您將清楚地將“轉換”部分與您的結構的特定規則處理分開。


查看完整回答
反對 回復 2021-11-22
?
jeck貓

TA貢獻1909條經驗 獲得超7個贊

你可以只編組/解組,但屬性名稱應該匹配


func CreateFromMap(m map[string]interface{}) (MyStruct, error) {

    data, _ := json.Marshal(m)

    var result MyStruct

    err := json.Unmarshal(data, &result)

    return result, err

}


查看完整回答
反對 回復 2021-11-22
  • 2 回答
  • 0 關注
  • 163 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號