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) {}
假如共用的代码段太长,这样岂不是太难看了
1
ypcs03 2019-08-27 13:16:50 +08:00 via Android
你确定 interface 能当作 key ?
|
3
mornlight 2019-08-27 13:31:12 +08:00
目测一下放 switch 外面不行,外面的 s 还是 interface{},k, v 推断不出来类型了。
|
4
Vegetable 2019-08-27 13:45:46 +08:00
golang 是静态类型,所以你没办法改变对象的类型,只能改变他的值。
s 是 interface{},那他在作用域中就永远是 interface 了。你这个写法就算是放在 switch 里边也不能 for,因为 s 依然还是 interface{},必须是在 switch 里指定一个新的值才行。 |
5
SuperMild 2019-08-27 13:50:43 +08:00
这句
case Obj: for k, v := range s.(Obj) {} 你把 s 后面的 ".(Obj)" 删掉试试,隐约记得是可以的。 |
6
whoami9894 OP |
7
whoami9894 OP @SuperMild
不行的,`cannot range over interface{}` |
8
SuperMild 2019-08-27 14:09:15 +08:00
你用了 interface{} 做 key,因此这个 key 也需要断言,让它落实到一个 comparable 类型才行的。
map keys may be of any type that is comparable. |
9
SuperMild 2019-08-27 14:10:33 +08:00
是稍麻烦一点,先忍一忍吧,Go 很快就有泛型了。
|
10
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) } } } |
11
whoami9894 OP @reus
这样可以解决,学到了 |
12
zzlettle 2019-08-27 19:22:25 +08:00
没看懂
|
13
SuperMild 2019-08-27 19:36:26 +08:00
原来是这里漏了赋值(捂脸哭着笑) switch s := s.(type)
|
14
GreatHumorist 2019-08-27 19:48:16 +08:00
定义接口实现接口,每个类型都实现一个 foo 方法,类似 json 的 unmarshal
|
15
whoami9894 OP @SuperMild
嗯。。我傻了,但赋了值也只在 switch 内可见,还是得在 switch 里写处理逻辑 |
16
whoami9894 OP @GreatHumorist
分别定义 method 还是会导致冗余代码 |