如何迭代解码器?

时间:2015-11-10 19:35:01

标签: go

我来自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
}

是否有某种方法可以将rangeDecoder接口一起使用?将它包装在不同界面中的功能将是理想的,并且可以接受惯用模式。

谢谢!

2 个答案:

答案 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

中循环所有JSON编码的值
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会更好。更新了代码段。