英文:
Can someone explain this interface example in Go?
问题
从http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go中有一个示例,说明了在Go中使用接口的可能用法。代码如下:
package main
import (
"encoding/json"
"fmt"
"reflect"
"time"
)
// 从一个字符串表示的JSON数据开始
var input = `
{
"created_at": "Thu May 31 00:00:01 +0000 2012"
}
`
type Timestamp time.Time
func (t *Timestamp) UnmarshalJSON(b []byte) error {
v, err := time.Parse(time.RubyDate, string(b[1:len(b)-1]))
if err != nil {
return err
}
*t = Timestamp(v)
return nil
}
func main() {
// 我们的目标类型将是map[string]interface{},这是一种非常通用的类型
// 它将给我们一个哈希表,其中键是字符串,值是interface{}类型
var val map[string]Timestamp
if err := json.Unmarshal([]byte(input), &val); err != nil {
panic(err)
}
fmt.Println(val)
for k, v := range val {
fmt.Println(k, reflect.TypeOf(v))
}
fmt.Println(time.Time(val["created_at"]))
}
运行结果如下:
map[created_at:{63474019201 0 0x59f680}]
created_at main.Timestamp
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:
package main
import (
"encoding/json"
"fmt"
"reflect"
"time"
)
// start with a string representation of our JSON data
var input = `
{
"created_at": "Thu May 31 00:00:01 +0000 2012"
}
`
type Timestamp time.Time
func (t *Timestamp) UnmarshalJSON(b []byte) error {
v, err := time.Parse(time.RubyDate, string(b[1:len(b)-1]))
if err != nil {
return err
}
*t = Timestamp(v)
return nil
}
func main() {
// our target will be of type map[string]interface{}, which is a pretty generic type
// that will give us a hashtable whose keys are strings, and whose values are of
// type interface{}
var val map[string]Timestamp
if err := json.Unmarshal([]byte(input), &val); err != nil {
panic(err)
}
fmt.Println(val)
for k, v := range val {
fmt.Println(k, reflect.TypeOf(v))
}
fmt.Println(time.Time(val["created_at"]))
}
with a result like this:
map[created_at:{63474019201 0 0x59f680}]
created_at main.Timestamp
2012-05-31 00:00:01 +0000 UTC
I am struggling to understand how the function call
json.Unmarshal([]byte(input), &val){...}
relates to the method defined earlier
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.Unmarshal
将val
的元素类型断言为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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论