将interface {}转换为某种类型

时间:2014-01-18 18:28:43

标签: casting go

我正在开发将接收JSON的Web服务。 Go转换类型太严格了。

所以我在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{}stringint等内转换int64的功能

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

更新

我的网络服务收到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"])

2 个答案:

答案 0 :(得分:9)

objx package完全符合您的要求,它可以直接使用JSON,并为您提供默认值和其他很酷的功能:

  

Objx提供objx.Map类型,即map[string]interface{}   这暴露了一个强大的Get方法(以及其他方法),允许你这样做   轻松快捷地访问地图中的数据,而无需访问   过分担心类型断言,缺少数据,默认值   等

这是一个小例子:

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库。

答案 1 :(得分:0)

最快/最好的方式是在时间执行中“快速”执行(如果您知道对象的话):

例如

package main    
import "fmt"    
func main() {
    var inter (interface{})
    inter = "hello"
    var value string
    value = inter.(string)
    fmt.Println(value)
}

Try here