doujiang2020 2015-08-28 18:07
浏览 38
已采纳

指针接收器混乱

I'm confused about the behaviour of the following code. playground

var foo json.RawMessage
_ = json.Unmarshal([]byte(`{ "zoo": 123 }`), &foo)

enc := json.NewEncoder(os.Stdout)

// Works as expected
_ = enc.Encode(struct{ Foo *json.RawMessage }{&foo})

// MarshalJSON has a pointer reciever, so it doesn't get invoked here
_ = enc.Encode(struct{ Foo json.RawMessage }{foo})

// How is MarshalJSON being invoked if .Foo is not a pointer?
_ = enc.Encode(&struct{ Foo json.RawMessage }{foo})

Output:

{"Foo":{"zoo":123}}
{"Foo":"eyAiem9vIjogMTIzIH0="}
{"Foo":{"zoo":123}}

I don't understand why the third call to json.Encoder.Encode is able to access json.RawMessage.MarshalJSON even though it's not a pointer.

  • 写回答

1条回答 默认 最新

  • dpklt4291 2015-08-28 18:56
    关注

    When calling a method on any addressable value, Go will automatically reference the value to call methods with a pointer receiver.

    type Foo struct{}
    func (f *Foo) Call() {}
    
    // f isn't a pointer, but is addressable
    f := Foo{}
    f.Call()
    

    Also, if a non-pointer value is in an addressable struct, it can also be reference for methods requiring a pointer receiver.

    type Bar struct {
        Foo Foo
    }
    
    // b is addressable, therefor so is b.Foo
    b := Bar{
        Foo: f,
    }
    b.Foo.Call()
    

    Your last example uses the address of the outer struct to get the address of the Foo field, and call MarshalJSON.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探