我希望将各种对象编组,然后解组它们,并通过获取被编组的变量类型将它们转换回原始类型。 关键是我想将未编组的对象转换为指定变量的类型,而不指定类型。
短伪码:
// Marshal this
item := Book{"The Myth of Sisyphus", "Albert Camus"}
// Then unmarshal and convert to the type of the item variable.
itemType := reflect.TypeOf(item)
newItem itemType = unmarshalledItem.(itemType) // This is the problem.
fmt.Println("Unmarshalled is:", reflect.TypeOf(newItem)) // Should print *main.Book
完整代码:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"reflect"
)
type Book struct {
Title string
Author string
}
func main() {
// Create objects to marshal.
book := Book{"The Myth of Sisyphus", "Albert Camus"}
box := make(map[string]interface{})
box["The Myth of Sisyphus"] = &book
itemType := reflect.TypeOf(box["The Myth of Sisyphus"])
fmt.Println("Book is:", itemType)
// Marshal objects to file.
err := Write(&book)
if err != nil {
fmt.Println("Unable to save store.", err)
return
}
// Unmarshal objects from file.
untyped := make(map[string]interface{})
bytes, err := ioutil.ReadFile("store.txt")
if err != nil {
fmt.Println("Unable to load store.", err)
return
}
err = json.Unmarshal(bytes, &untyped)
if err != nil {
fmt.Println("Err in store unmarshal.", err)
return
}
// Get Title property of unmarshalled object,
// and use that to get variable type from box map.
for k, v := range untyped {
if k == "Title" {
itemTitle := v.(string)
fmt.Println("Cast item having title:", itemTitle)
targetType := reflect.TypeOf(box[itemTitle])
fmt.Println("Type to cast to is:", targetType)
// Convert untyped to targetType.
// This is the problem.
typed targetType = untyped.(targetType)
fmt.Println("Unmarshalled is:", reflect.TypeOf(typed)) // Should print *main.Book
}
}
}
func Write(b *Book) error {
data, err := json.Marshal(b)
if err != nil {
return err
}
newFilename := "store.txt"
f, err := os.OpenFile(newFilename, os.O_CREATE|os.O_TRUNC, 0660)
if err != nil {
return err
}
_, err = f.WriteString(string(data) + "\n")
if err != nil {
return err
}
return nil
}
答案 0 :(得分:1)
这可能适用于动态类型语言,但它不会在这里工作,因为Go是静态类型的。
这本书没有存储为Book,它存储为json字符串,json unmarshaller不知道它是一本书,除非你这么说。即它不知道将字段映射到Book对象。
你不能将未编组的'无类型'转换成一本书,因为它不是一本书,它是一个地图[string] interface {},它恰好看起来像一本书。
您需要做的是
我猜是这样的事情:
// check the type
if targetType.String() == "*main.Book" {
// unmarshall it again as a Book
var typedBook Book
_ = json.Unmarshal(bytes, &typedBook)
fmt.Println("Unmarshalled is:", reflect.TypeOf(typedBook)) // Should print *main.Book
} else if targetType.String() == "*main.Magazine" {
// unmarshal a magazine or whatever
}