将interface{}转换为特定类型。

huangapple go评论105阅读模式
英文:

convert interface{} to certain type

问题

我正在开发一个接收 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{} 转换为 stringintint64 等类型。

所以我的问题是:在 Go 语言中是否有一个库(一组函数)可以将 interface{} 转换为特定的类型?

更新

我的 Web 服务接收 JSON 数据。我将其解码为 map[string]interface{},我无法控制编码过程。

所以我接收到的所有值都是 interface{} 类型,我需要一种将其转换为特定类型的方法。

它可以是 nilintfloat64string[...]{...},我希望能将其转换为应该的类型,例如 intfloat64string[]stringmap[string]string,并处理所有可能的情况,包括 nil、错误的值等。

更新2

我接收到的 JSON 数据有以下几种形式:{"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"])

希望这些能帮到你!

英文:

I am developing web service that will receive JSON. Go converts types too strict.

So I did following function to convert interface{} in 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
}

I believe that function is still not perfect and I need functions to convert interface{} in string, int, int64, etc

So my question: Is there library (set of functions) in Go that will convert interface{} to certain types

UPDATE

My web service receive JSON. I decode it in map[string]interface{} I do not have control on those who encode it.

So all values I receive are interface{} and I need way to cast it in certain types.

So it could be nil, int, float64, string, [...], {...} and I wish to cast it to what it should be. e.g. int, float64, string, []string, map[string]string with handling of all possible cases including nil, wrong values, etc

UPDATE2

I receive {"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"])

答案1

得分: 11

objx包可以完全满足你的需求,它可以直接处理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的示例:

// 使用MustFromJSON从一些JSON中创建objx.Map
m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`)

// 获取详细信息
name := m.Get("name").Str()
age := m.Get("age").Int()

// 获取他们的昵称(如果没有昵称,则使用他们的名字)
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访问器,你会看到一个类似于这个的复杂代码,但有许多用法的情况,所以我认为最好的解决方案是使用objx库。

英文:

objx package makes exactly what you want, it can work directly with JSON, and will give you default values and other cool features:

> Objx provides the objx.Map type, which is a map[string]interface{}
> that exposes a powerful Get method (among others) that allows you to
> easily and quickly get access to data within the map, without having
> to worry too much about type assertions, missing data, default values
> etc.

This is a small example of the usage:

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

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

A example from doc working with JSON:

// 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)

Obviously you can use something like this with the plain runtime:

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

But if you check objx accessors you can see a complex code similar to this but with many case of usages, so i think that the best solution is use objx library.

答案2

得分: 6

快速/最佳的方法是在执行时使用“Cast”(如果你知道对象):

例如:

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

在这里尝试

英文:

Fast/Best way is 'Cast' in time execution (if you know the object):

E.g.

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

Try here

答案3

得分: 4

我来试着将interface{}转换为bool,并且Reflect给了我一个简洁的方法:

假设有以下代码:

v := interface{}
v = true

解决方案1:

if value, ok := v.(bool); ok {
  //你可以使用变量`value`
}

解决方案2:

reflect.ValueOf(v).Bool()

然后,reflect提供了一个获取所需类型的函数。

英文:

I came here trying to convert from interface{} to bool and Reflect gave me a clean way to do it:

Having:

v := interface{}
v = true

The solution 1:

if value, ok := v.(bool); ok {
  //you can use variable `value`
}

The solution 2:

reflect.ValueOf(v).Bool()

Then reflect offers a function for the Type you need.

huangapple
  • 本文由 发表于 2014年1月19日 02:28:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/21208120.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定