promoted Unmarshal method on embedded field caused confusion 后续

encoding/json: promoted Unmarshal method on embedded field caused confusionweb

接上一篇,官方在早上给了回复:json

简单解释下就是嵌入字段 Nested 的方法被提高了,致使 Object 的方法不会被执行,因此 Num 字段不会被 Unmarshal。跟上一篇中的解释差很少意思。可是官方给了两种更加优雅的解决这个问题的方式,让咱们来欣赏下大佬的代码。编辑器

方法 a

代码中只需添加下面一行便可:ide

var _ json.Unmarshaler = (*Object)(nil)
复制代码
package main
 import (  "encoding/json"  "fmt"  "time" )  var testJSON = `{"num":5,"duration":"5s"}`  type Nested struct {  Dur time.Duration `json:"duration"` }  func (obj *Object) UnmarshalJSON(data []byte) error {  tmp := struct {  Dur string `json:"duration"`  Num int `json:"num"`  }{}  if err := json.Unmarshal(data, &tmp); err != nil {  return err  }   dur, err := time.ParseDuration(tmp.Dur)  if err != nil {  return err  }  obj.Dur = dur  obj.Num = tmp.Num  return nil }  type Object struct {  Nested  Num int `json:"num"` }  var _ json.Unmarshaler = (*Object)(nil)  func main() {  obj := Object{}  _ = json.Unmarshal([]byte(testJSON), &obj)  fmt.Printf("result: %+v \n", obj) } 复制代码

随后这位老哥补充到,在嵌入字段都实现了接口方法的状况下,The type assertion will be a nice guide, 添加该类型的断言是一个好的实践,能够帮助你快速捕捉到潜在的 bug学习

方法 b

实现 custom time unmarshallerui

package main
 import (  "encoding/json"  "fmt"  "time" )  var testJSON = `{"num":5,"duration":"5s"}`  type customTimeDuration time.Duration  type Nested struct {  Dur customTimeDuration `json:"duration"` }  func (ctd *customTimeDuration) UnmarshalJSON(b []byte) error {  var durStr string  if err := json.Unmarshal(b, &durStr); err != nil {  return err  }  dur, err := time.ParseDuration(durStr)  if err == nil {  *ctd = customTimeDuration(dur)  }  return err }  type Object struct {  Nested  Num int `json:"num"` }  func main() {  obj := Object{}  _ = json.Unmarshal([]byte(testJSON), &obj)  fmt.Printf("result: %+v \n", obj) } 复制代码

这种方式其实就是跟以上一篇分开解析的思路比较像,他从新声明了别名类型,而后为这个别名类型实现 UnmarshalJson 接口。我的倾向于第一种添加类型断言的方式,简洁又容易理解 ,对代码侵入比较小。url

官方对这个问题的回复仍是很热情的,他说他本身的团队在几年前也遇到了如出一辙的问题,很能理解开发者的心情,他当时还针对这个问题写了一篇相似的文章,https://medium.com/@odeke_et/compile-type-assertions-to-the-rescue-6ddab4b8398b。我说啥来着,这是一个前人踩坑,后人踩坑,将来还会踩的坑。spa

u1s1, 这位大佬给出的方案和代码仍是很赏心悦目的,值得学习(抄一下)。code

------------------------------ END ----------------------------------cdn

相关文章
相关标签/搜索