2017-10-13 8 views
0

カスタムJSONマーマーを実装しましたが、何らかの理由で適切な値が返されません。すべてのフィールドがnilに戻ります。例えばカスタムjson unmarshalerが空のフィールドを返す

&main.test{t:""}
それがフィールドを非整列化しない理由:

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:"hello"}

上記のポインタを参照解除する場合にのみ、目的の結果が得られます。

すなわち -

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

答えて

1

あなたはtestにもポインタローカル変数tt、の値に、ローカル変数ttestへのポインタを代入しています。これは、元のポインタ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

関連する問題