我在Go中的菜鸟:)所以我的问题可能是愚蠢的,但无法找到答案,所以。
我需要一个功能:
func name (v interface{}) {
if is_slice() {
for _, i := range v {
my_var := i.(MyInterface)
... do smth
}
} else {
my_var := v.(MyInterface)
... do smth
}
}
如何在Go中执行is_slice
?感谢任何帮助。
答案 0 :(得分:7)
在您的情况下,type switch是最简单,最方便的解决方案:
func name(v interface{}) {
switch x := v.(type) {
case []MyInterface:
fmt.Println("[]MyInterface, len:", len(x))
for _, i := range x {
fmt.Println(i)
}
case MyInterface:
fmt.Println("MyInterface:", x)
default:
fmt.Printf("Unsupported type: %T\n", x)
}
}
case
分支枚举了可能的类型,而x
变量中的type MyInterface interface {
io.Writer
}
var i MyInterface = os.Stdout
name(i)
var s = []MyInterface{i, i}
name(s)
name("something else")
变量已经属于该类型,因此您可以使用它。
测试它:
MyInterface: &{0x1040e110}
[]MyInterface, len: 2
&{0x1040e110}
&{0x1040e110}
Unsupported type: string
输出(在Go Playground上尝试):
if x, ok := v.([]MyInterface); ok {
// x is of type []MyInterface
for _, i := range x {
fmt.Println(i)
}
} else {
// x is not of type []MyInterface or it is nil
}
对于单一类型检查,您还可以使用type assertion:
{{article.url}}
还有其他方法,使用包reflect
你可以写一个更通用(和更慢)的解决方案,但如果你刚刚开始Go,你就不应该深入研究。
答案 1 :(得分:3)
icza's answer是正确的,但go creators不推荐
interface {}什么都没说
更好的方法可能是为您拥有的每种类型定义一个函数:
func name(v MyInterface) {
// do something
}
func names(vs []MyInterface) {
for _, v := range(vs) {
name(v)
}
}
答案 2 :(得分:0)
来自https://blog.golang.org/json
解码任意数据
考虑此存储在变量b中的JSON数据:
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
在不知道此数据结构的情况下,我们可以使用Unmarshal将其解码为interface {}值:
var f接口{} 错误:= json.Unmarshal(b,&f) 此时,f中的Go值将是一个映射,该映射的键是字符串,并且其值本身存储为空接口值:
f = map[string]interface{}{
"Name": "Wednesday",
"Age": 6,
"Parents": []interface{}{
"Gomez",
"Morticia",
},
}
要访问此数据,我们可以使用类型断言来访问f的基础map [string] interface {}:
m := f.(map[string]interface{})
然后我们可以使用range语句遍历地图,并使用类型开关将其值作为其具体类型来访问:
for k, v := range m {
switch vv := v.(type) {
case string:
fmt.Println(k, "is string", vv)
case float64:
fmt.Println(k, "is float64", vv)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range vv {
fmt.Println(i, u)
}
default:
fmt.Println(k, "is of a type I don't know how to handle")
}
}
通过这种方式,您可以使用未知的JSON数据,同时仍可以享受类型安全的好处。
答案 3 :(得分:0)
is_slice
方法可以是这样的:
func IsSlice(v interface{}) bool {
return reflect.TypeOf(v).Kind() == reflect.Slice
}
如果需要,也可以添加额外的 reflect.TypeOf(v).Kind() == reflect.Array
条件。