Golang:嵌套JSON Unmarshaler遇到麻烦
给出以下代码:
package mainimport (
"encoding/json"
"log"
)
type Somefin string
func (s *Somefin) UnmarshalJSON(b []byte) error {
log.Println("Unmarshaling",string(b))
*s = Somefin("~"+string(b)+"~")
return nil
}
type Wat struct {
A, B string
*Somefin
}
func main() {
b := []byte(`{"A":"foo","B":"bar","Somefin":"baz"}`)
w := &Wat{Somefin: new(Somefin)}
err := json.Unmarshal(b,w)
log.Println(w, err)
}
我得到以下输出:
# go run wat.go2013/12/14 13:59:17 Unmarshaling {"A":"foo","B":"bar","Somefin":"baz"}
2013/12/14 13:59:17 &{ <nil>} <nil>
因此,Somefin
出于某种原因,密钥是试图取消对整个结构的编组,而不是仅仅应该解组。我做错了吗,或者这是json编码器中的错误?顺便说一句,正在进行1.2。
回答:
为什么最后没有结果
这不是解码器中的错误,而是代码中的错误。你只是将另一个地址为本地指针s
在UnmarshalJSON
。更正的代码:
func (s *Somefin) UnmarshalJSON(b []byte) error { log.Println("Unmarshaling",string(b))
sn := Somefin("~"+string(b)+"~")
*s = sn
return nil
}
语义s = &sn
:将地址分配&sn
给s
。这类似于s = 42
。
的语义*s = sn
:将所有内容复制sn
到指向的地方s
。
这项工作的一项要求是s
指向有效的内存位置,并且不能为nil
。您的代码用法示例(播放):
w := &Wat{Somefin: new(Somefin)}err := json.Unmarshal(b,w)
log.Printf("%#v (%s)\n", w, err)
Crucial是Wat
使用new进行的初始化,Somefin
因此s
in
的指针UnmarshalJSON
有效(指向使用创建的对象new(Somefin)
)。
为什么要输入整个字符串 UnmarshalJSON
嵌入不是多态。虽然嵌入对象(在你的情况的方法集 Somefin
)提升到外面,但这 并不 意味着该方法现在工作的嵌入结构,而不是嵌入的一个。
小例子(播放):
type Inner struct { a int }func (i *Inner) A() int { return i.a }
type Outer struct {
*Inner
a int
}
i := &Inner{}
o := Outer{Inner: i}
fmt.Println("Inner.A():", i.A())
fmt.Println("Outer.A():", o.A())
o.a = 2
fmt.Println("Outer.A():", o.A())
有了多态,您将希望Outer.A()
返回,2
因为方法A()
将在范围内运行,Outer
并且Inner
不再运行。嵌入后,作用域A()
将永远不会改变,并且
将始终在上运行Inner
。
相同的效果会阻止您UnmarshalJSON
看到这两个成员A
,B
因为它们根本不在以下范围内Somefin
:
- JSON库看到
UnmarshalJSON
的Wat
,因为UnmarshalJSON
从Somefin
被提升到外 - JSON库无法在其中找到任何匹配的元素
Somefin
并提供整个输入
以上是 Golang:嵌套JSON Unmarshaler遇到麻烦 的全部内容, 来源链接: utcz.com/qa/422336.html