2 回答

TA貢獻(xiàn)1797條經(jīng)驗 獲得超4個贊
假設(shè)我假設(shè)您不想使用反射,因為您不想自己做。在這種情況下,如何使用為您執(zhí)行此操作的外部包?
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}
無論您的結(jié)構(gòu)是什么樣子,它都有優(yōu)勢,但它在內(nèi)部使用反射。實際上,如果不對結(jié)構(gòu)的每個屬性使用反射和/或重復(fù)代碼,我看不到任何“好”的方法來做您想做的事情。但是,缺點(diǎn)是您必須使用大寫的屬性,以便將它們導(dǎo)出到外部包。
編輯(在評論中回答您的問題):
在我看來,如果要在“創(chuàng)建”結(jié)構(gòu)時指定附加規(guī)則,應(yīng)該在解碼操作之后。例如:
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
}
這樣,您將清楚地將“轉(zhuǎn)換”部分與您的結(jié)構(gòu)的特定規(guī)則處理分開。

TA貢獻(xiàn)1909條經(jīng)驗 獲得超7個贊
你可以只編組/解組,但屬性名稱應(yīng)該匹配
func CreateFromMap(m map[string]interface{}) (MyStruct, error) {
data, _ := json.Marshal(m)
var result MyStruct
err := json.Unmarshal(data, &result)
return result, err
}
- 2 回答
- 0 關(guān)注
- 160 瀏覽
添加回答
舉報