英文:
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{}
转换为 string
、int
、int64
等类型。
所以我的问题是:在 Go 语言中是否有一个库(一组函数)可以将 interface{}
转换为特定的类型?
更新
我的 Web 服务接收 JSON 数据。我将其解码为 map[string]interface{}
,我无法控制编码过程。
所以我接收到的所有值都是 interface{}
类型,我需要一种将其转换为特定类型的方法。
它可以是 nil
、int
、float64
、string
、[...]
、{...}
,我希望能将其转换为应该的类型,例如 int
、float64
、string
、[]string
、map[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)
}
答案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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论