键入递归golang函数调用

时间:2013-05-15 03:05:33

标签: json parsing recursion go

我正在努力将“数组通配符”添加到Github上名为jsonget的Go项目中。以下是数组通配符的含义示例:

 > echo "[{product:'coffee', price:2.10}, {product:'beer', price:3.80}]" | jsonget '*.price'

[2.10, 3.80]

我的分支代码是here

我遇到的问题是键入,当GetValue遇到*字符时,它会递归,在子表达式上调用GetValue,但类型总是以字符串形式返回

例如,在测试文件中,我给它一块json:

    {
      "inventory": [
          {"name": "mountain bike", "price": 251.0},
          {"name": "red wagon", "price": 90.10},
          {"name": "kinesis advantage", "price": 300.0},
          {"name": "a ticket to Mars", "price": 1200000000.0}
      ]
    }

然后查询inventory[*].price,期待[251,90.1,300,1.2e+09],而不是["251","90.1","300","1.2e+09"]

我想避免在这里使用反射,但我没有看到另一种方法来做到这一点。

1 个答案:

答案 0 :(得分:1)

如果我误解了你的问题,我很抱歉,但希望这会有所帮助。

我认为您要么必须使用反射或类型切换(http://golang.org/doc/effective_go.html#type_switch,这可能会在幕后使用反射,而不是确定)。

修改现有的valueToString函数以包含类型开关应该不会太难。可能将其重命名为convertValue或更通用的东西,并在其中放置一个类型开关。如果值是int,则返回int,否则返回一个字符串。

例如:

func convertValue(value interface{}) (text string, i int, err error) { // Was valueToString
    if value == nil && *printNulls == false {
        return "", nil, nil
    }

    textBytes, err := json.Marshal(value)
    if err != nil {
        return "", nil, err
    }
    switch value := value.(type) {
    default:
        text = string(textBytes)
        text = quotedString.ReplaceAllString(text, "$1")
        return text, nil, nil
    case int:
        i = textBytes
        return nil, i, nil
    }
}

这将希望 string()除了类型开关检测为int的值之外的所有内容,它们将按原样返回。

可能有一种更简洁的方法,但它几乎肯定会涉及大型代码重构。主要的缺点是现在你需要在使用它之前检查一个值是否为零。

我不确定是否有办法让一个函数能够返回各种类型的值,因为我很确定它会对类型安全造成严重破坏。如果有可能,我只能通过返回函数定义中的空接口来实现。听起来很乱。

编辑:查看Andrew Gerrand的博文http://blog.golang.org/2011/01/json-and-go.html,特别是关于解码通用数据的底线。它应该有所帮助。

相关问题