2014-01-18 48 views
6

我正在开发将接收JSON的Web服务。去转换类型太严格。将接口{}转换为某种类型

没等我下面的函数interface{}转换成bool

func toBool(i1 interface{}) bool { 
    if i1 == nil { 
     return false 
    } 
    switch i2 := i1.(type) { 
    default: 
     return false 
    case bool: 
     return i2 
    case string: 
     return i2 == "true" 
    case int: 
     return i2 != 0 
    case *bool: 
     if i2 == nil { 
      return false 
     } 
     return *i2 
    case *string: 
     if i2 == nil { 
      return false 
     } 
     return *i2 == "true" 
    case *int: 
     if i2 == nil { 
      return false 
     } 
     return *i2 != 0 
    } 
    return false 
} 

我认为,功能还不够完善,我需要的功能转换interface{}stringintint64

所以我问题:Go中是否有库(函数集)会将interface{}转换为某些类型

UPDATE

我的web服务接收JSON。我在map[string]interface{}中解码,我无法控制编码它的人。

因此,我收到的所有值都是interface{},我需要将其转换为某些类型。

所以它可能是nilintfloat64string[...]{...},我希望把它转换为它应该是什么。例如intfloat64string[]stringmap[string]string与所有可能的情况,包括nil,错误的价值观处理等

UPDATE2

我收到{"s": "wow", "x":123,"y":true}{"s": 123, "x":"123","y":"true"}{a:["a123", "a234"]}{}

var m1 map[string]interface{} 
json.Unmarshal(b, &m1) 
s := toString(m1["s"]) 
x := toInt(m1["x"]) 
y := toBool(m1["y"]) 
arr := toStringArray(m1["a"]) 
+0

我不认为有一个。 – Agis

+0

你知道Go的'encoding/json'包会为你做所有事情,对吧?但无论如何,反射库可以查看界面并告诉你真正的底层值是什么,如果这就是你的意思。 –

+1

为什么?你能告诉我更多关于你想要解决的现实世界问题吗? - 你知道https://gobyexample.com/json吗? – Matthias

回答

6

objx package正是你想要的,它可以直接使用易

物objx提供objx.Map类型,这是一个map[string]interface{} 暴露了强大Get方法(等等),让您 并迅速得到访问:JSON,并会给你默认值和其他很酷的功能到地图内的数据,而不必 担心类型的断言,丢失的数据,默认值太多 等

这是使用的一个小例子:

o := objx.New(m1) 
s := o.Get("m1").Str() 
x := o.Get("x").Int() 
y := o.Get("y").Bool() 

arr := objx.New(m1["a"]) 

JSON的一个从DOC例如:

// use MustFromJSON to make an objx.Map from some JSON 
m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`) 

// get the details 
name := m.Get("name").Str() 
age := m.Get("age").Int() 

// get their nickname (or use their name if they 
// don't have one) 
nickname := m.Get("nickname").Str(name) 

很明显,你可以使用类似这样与平原运行时:

switch record[field].(type) { 
case int: 
    value = record[field].(int) 
case float64: 
    value = record[field].(float64) 
case string: 
    value = record[field].(string) 
} 

但如果你检查objx accessors可以看到复杂的代码类似于此,但有许多用法的情况下,所以我认为最好的解决方案是使用objx库。

相关问题