有人可以解释一下这个 Go 语言的接口示例吗?

huangapple go评论120阅读模式
英文:

Can someone explain this interface example in Go?

问题

从http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go中有一个示例,说明了在Go中使用接口的可能用法。代码如下:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "reflect"
  6. "time"
  7. )
  8. // 从一个字符串表示的JSON数据开始
  9. var input = `
  10. {
  11. "created_at": "Thu May 31 00:00:01 +0000 2012"
  12. }
  13. `
  14. type Timestamp time.Time
  15. func (t *Timestamp) UnmarshalJSON(b []byte) error {
  16. v, err := time.Parse(time.RubyDate, string(b[1:len(b)-1]))
  17. if err != nil {
  18. return err
  19. }
  20. *t = Timestamp(v)
  21. return nil
  22. }
  23. func main() {
  24. // 我们的目标类型将是map[string]interface{},这是一种非常通用的类型
  25. // 它将给我们一个哈希表,其中键是字符串,值是interface{}类型
  26. var val map[string]Timestamp
  27. if err := json.Unmarshal([]byte(input), &val); err != nil {
  28. panic(err)
  29. }
  30. fmt.Println(val)
  31. for k, v := range val {
  32. fmt.Println(k, reflect.TypeOf(v))
  33. }
  34. fmt.Println(time.Time(val["created_at"]))
  35. }

运行结果如下:

  1. map[created_at:{63474019201 0 0x59f680}]
  2. created_at main.Timestamp
  3. 2012-05-31 00:00:01 +0000 UTC

我很难理解函数调用json.Unmarshal([]byte(input), &val)与之前定义的方法func (t *Timestamp) UnmarshalJSON(b []byte) error之间的关系。阅读http://golang.org/pkg/encoding/json/#Unmarshal上的文档更加令我困惑。

显然我在这里漏掉了一些东西,但我无法弄清楚。

英文:

From http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go there an example illustrating a possible use of interfaces in Go. Code as below:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "reflect"
  6. "time"
  7. )
  8. // start with a string representation of our JSON data
  9. var input = `
  10. {
  11. "created_at": "Thu May 31 00:00:01 +0000 2012"
  12. }
  13. `
  14. type Timestamp time.Time
  15. func (t *Timestamp) UnmarshalJSON(b []byte) error {
  16. v, err := time.Parse(time.RubyDate, string(b[1:len(b)-1]))
  17. if err != nil {
  18. return err
  19. }
  20. *t = Timestamp(v)
  21. return nil
  22. }
  23. func main() {
  24. // our target will be of type map[string]interface{}, which is a pretty generic type
  25. // that will give us a hashtable whose keys are strings, and whose values are of
  26. // type interface{}
  27. var val map[string]Timestamp
  28. if err := json.Unmarshal([]byte(input), &val); err != nil {
  29. panic(err)
  30. }
  31. fmt.Println(val)
  32. for k, v := range val {
  33. fmt.Println(k, reflect.TypeOf(v))
  34. }
  35. fmt.Println(time.Time(val["created_at"]))
  36. }

with a result like this:

  1. map[created_at:{63474019201 0 0x59f680}]
  2. created_at main.Timestamp
  3. 2012-05-31 00:00:01 +0000 UTC

I am struggling to understand how the function call

  1. json.Unmarshal([]byte(input), &val){...}

relates to the method defined earlier

  1. func (t *Timestamp) UnmarshalJSON(b []byte) error{...}

Reading the doc at http://golang.org/pkg/encoding/json/#Unmarshal is confusing me even more.

I am obviously missing something here, but I can't figure it out.

答案1

得分: 3

在Go语言中,接口的实现只需要实现其方法。这与大多数其他流行的语言(如Java、C#、C++)非常不同,在这些语言中,类接口必须在类声明中明确指出。

关于这个概念的详细解释可以在Go文档中找到:https://golang.org/doc/effective_go.html#interfaces

因此,func (t *Timestamp) UnmarshalJSON(...)定义了一个方法,并同时实现了接口。然后,json.Unmarshalval的元素类型断言为Unmarshaler接口(http://golang.org/pkg/encoding/json/#Unmarshaler),并调用UnmarshalJSON方法从字节切片构造它们。

英文:

In Go an interface is implemented just by implementing its methods. It is so much different from the most other popular languages (Java, C#, C++) in which the class interfaces should be explicitly mentioned in the class declaration.

The detailed explanation of this concept you can find in the Go documentation: https://golang.org/doc/effective_go.html#interfaces

So the func (t *Timestamp) UnmarshalJSON(...) defines a method and in a same time implements the interface. The json.Unmarshal then type asserts the elements of val to the Unmarshaler interface (http://golang.org/pkg/encoding/json/#Unmarshaler) and call the UnmarshalJSON method to construct them from the byte slice.

huangapple
  • 本文由 发表于 2014年9月25日 17:34:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/26035172.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定