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

2019 年 8 月 27 日
 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) {}

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

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

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

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

map keys may be of any type that is comparable.
SuperMild
2019 年 8 月 27 日
是稍麻烦一点,先忍一忍吧,Go 很快就有泛型了。
reus
2019 年 8 月 27 日
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 年 8 月 27 日
@reus
这样可以解决,学到了
zzlettle
2019 年 8 月 27 日
没看懂
SuperMild
2019 年 8 月 27 日
原来是这里漏了赋值(捂脸哭着笑) switch s := s.(type)
GreatHumorist
2019 年 8 月 27 日
定义接口实现接口,每个类型都实现一个 foo 方法,类似 json 的 unmarshal
whoami9894
2019 年 8 月 27 日
@SuperMild
嗯。。我傻了,但赋了值也只在 switch 内可见,还是得在 switch 里写处理逻辑
whoami9894
2019 年 8 月 27 日
@GreatHumorist
分别定义 method 还是会导致冗余代码

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

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

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

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

© 2021 V2EX