2013-05-15 11 views
0

我正在为Github上的Go项目添加'array wildcards',名为jsonget。下面是我所说的阵列通配符意味着一个例子:在递归golang函数调用中键入

> 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"]

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

+0

发布突出显示该问题的代码片段会很有帮助。 –

+0

你的库在'main'包中定义 - 你应该修复你的项目结构。 – thwd

回答

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()一切只是将式开关检测为整数的值,因为它们将被返回。

有可能是一个更干净的方式,但它几乎肯定会涉及一个大的代码重构。主要的缺点是,现在你需要检查一个值是否为零,然后再使用它。

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

编辑:看看安德鲁杰兰德的博客文章http://blog.golang.org/2011/01/json-and-go.html,特别是关于解码通用数据的底部附近的位。它应该有所帮助。