GO 的这种情况下该如何使用类型断言

2019-08-27 13:05:03 +08:00
 whoami9894
type Obj map[interface{}]interface{}
type JSON map[string]interface{}

func foo(s interface{}) {
    switch s.(type) {
    case Obj:
        s = s.(Obj)
    case JSON:
        s = s.(JSON)
    }
    
    for k, v := range s {
        // do sth
    }
}

上面的情况会报cannot range over obj (type interface {})

那么这种情况该怎么写,是不是只能把后面 range 的处理逻辑写在 case 里了,像这样:

case Obj:
    for k, v := range s.(Obj) {}

假如共用的代码段太长,这样岂不是太难看了

2381 次点击
所在节点    问与答
16 条回复
ypcs03
2019-08-27 13:16:50 +08:00
你确定 interface 能当作 key ?
cloverstd
2019-08-27 13:19:16 +08:00
@ypcs03 #1 能呢
mornlight
2019-08-27 13:31:12 +08:00
目测一下放 switch 外面不行,外面的 s 还是 interface{},k, v 推断不出来类型了。
Vegetable
2019-08-27 13:45:46 +08:00
golang 是静态类型,所以你没办法改变对象的类型,只能改变他的值。
s 是 interface{},那他在作用域中就永远是 interface 了。你这个写法就算是放在 switch 里边也不能 for,因为 s 依然还是 interface{},必须是在 switch 里指定一个新的值才行。
SuperMild
2019-08-27 13:50:43 +08:00
这句

case Obj:
for k, v := range s.(Obj) {}

你把 s 后面的 ".(Obj)" 删掉试试,隐约记得是可以的。
whoami9894
2019-08-27 13:55:11 +08:00
@mornlight
@Vegetable
那就只能写冗余代码了,没泛型的痛啊。。。
whoami9894
2019-08-27 13:55:38 +08:00
@SuperMild
不行的,`cannot range over interface{}`
SuperMild
2019-08-27 14:09:15 +08:00
你用了 interface{} 做 key,因此这个 key 也需要断言,让它落实到一个 comparable 类型才行的。

map keys may be of any type that is comparable.
SuperMild
2019-08-27 14:10:33 +08:00
是稍麻烦一点,先忍一忍吧,Go 很快就有泛型了。
reus
2019-08-27 15:33:39 +08:00
type Obj map[interface{}]interface{}
type JSON map[string]interface{}

func foo(s interface{}) {
do := func(k interface{}, v interface{}) {
// do something
}

switch s := s.(type) {
case Obj:
for k, v := range s {
do(k, v)
}
case JSON:
for k, v := range s {
do(k, v)
}
}

}
whoami9894
2019-08-27 18:53:58 +08:00
@reus
这样可以解决,学到了
zzlettle
2019-08-27 19:22:25 +08:00
没看懂
SuperMild
2019-08-27 19:36:26 +08:00
原来是这里漏了赋值(捂脸哭着笑) switch s := s.(type)
GreatHumorist
2019-08-27 19:48:16 +08:00
定义接口实现接口,每个类型都实现一个 foo 方法,类似 json 的 unmarshal
whoami9894
2019-08-27 22:02:18 +08:00
@SuperMild
嗯。。我傻了,但赋了值也只在 switch 内可见,还是得在 switch 里写处理逻辑
whoami9894
2019-08-27 22:04:34 +08:00
@GreatHumorist
分别定义 method 还是会导致冗余代码

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/595512

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX