我来自Python背景,因此倾向于根据迭代器进行思考。在我看来,Go中的range
关键字打算让我们以几乎相同的方式思考,所以我想在语义上做一些与Go中的Python代码等效的东西:
for obj in json_decoder:
# business logic
这是Go的激励案例;考虑以下功能:
func (c *GorpController) Create(dec *json.Decoder) {
// business logic
}
我希望能够将其实现为:
for someValue := range dec {
// business logic
}
是否有某种方法可以将range
与Decoder
接口一起使用?将它包装在不同界面中的功能将是理想的,并且可以接受惯用模式。
谢谢!
答案 0 :(得分:3)
不幸的是,您只能将range
与“数组,切片,字符串或地图,或从频道中读取”(请参阅effective go)
在结构解码时迭代结构,文档建议:
dec := json.NewDecoder(strings.NewReader(jsonStream))
for {
var m Message
if err := dec.Decode(&m); err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
}
fmt.Printf("%s: %s\n", m.Name, m.Text)
}
(直接取自official doc example)
答案 1 :(得分:1)
A json.Decoder
是一个结构,在Go中,您只能对字符串,切片/数组,地图和通道(https://golang.org/ref/spec#For_statements)进行迭代(使用range
)。
但是,您可以在io.Reader
:
func main() {
s := `"a string"
72
["an", "array"]
{"an": "object"}
`
dec := json.NewDecoder(strings.NewReader(s))
for {
var v interface{}
if err := dec.Decode(&v); err != nil {
if err == io.EOF {
break
}
log.Fatal(err)
}
log.Print(v)
}
}
http://play.golang.org/p/flqXlcx_6B
编辑:虽然More
似乎确实适用于此示例中的值,但它不是它的预期用法(基于godoc),因此检查err == io.EOF会更好。更新了代码段。