2017-10-13 154 views
0

我已经实现了一个自定义JSON解组器,但由于某种原因它不会返回正确的值 - 所有字段都会返回零。自定义json unmarshaler返回空字段

例如:

type test struct { 
    t string 
} 


func New(data string) (*test, error) { 
    return &test{t: data}, nil 
} 

func (t *test) UnmarshalJSON(b []byte) error { 
     tt, err := New(string(b)) 
    if err != nil { 
     return err 
    } 
    t = tt 
    return nil 
} 

func main() { 
    str := `"hello"` 

    b := []byte(str) 
    t := &test{} 
    err := json.Unmarshal(b, t) 
    if err != nil { 
    fmt.Printf("unmarshal error occurred: %#v", err) 
    } 
    fmt.Printf("%#v", t) 
} 

https://play.golang.org/p/LuXkZQZHWz

上面的代码显示输出:&main.test{t:""}
为什么没有解组的字段?即&main.test{t:"hello"}

只有当我取消引用上面的指针时,才能得到期望的结果。

即 -

func (t *test) UnmarshalJSON(b []byte) error { 
     tt, err := New(string(b)) 
    if err != nil { 
     return err 
    } 
    *t = *tt 
    return nil 
} 

回答

1

你分配的局部变量t,指针test,局部变量tt的价值,也是一个指针test。这对原指针t指向的值没有影响。你必须解引用指针来改变它指向的值,而不是改变本地指针本身:

*t = *tt 
+0

你能详细说明一下吗?因此,将一个指针指向一个指针实际上什么都不做?我会期待't = tt'赋值将'tt'的地址赋值为't' – elimist3

+0

变量't'是该方法中的一个指针变量。如果你改变了那个指针的值,你改变了它指向的内容,而不是它最初指向的内容。改变它指出的内容不会改变原始结构。 Go中的方法接收器与C++这样的语言中的'this' /'self'指针不同,它们是任何其他值的变量。改变它们的唯一方法是传播出函数,如果你改变它们指向的值。 – Kaedys

+0

这可能会解释:https://play.golang.org/p/tBCM0PfpEO。请注意,t中保存的地址在该方法中发生了变化,并指向已正确解组的结构,但由于您更改了“t”本身的值而不是它指向的值,所以该更改不会传播出去。 – Kaedys