在此应用程序中,我有15种自定义类型,而我希望对它们进行的处理实际上对它们都非常通用。
在每种情况下,我都需要遍历我正在使用的任何类型的切片。
接口是当前通过的接口,但不必一定要保持这种状态
我有以下代码:
func ProcessSlice(in interface{}){
switch reflect.TypeOf(p.in).Kind() {
case reflect.Slice:
s := reflect.ValueOf(p.in)
for i := 0; i < s.Len(); i++ {
fmt.Println(reflect.ValueOf(p.in))
}
}
}
fmt.Println用于调试,我得到以下输出:
[map[_Id:4K7qx_mUSbV-----------== name:<name ommited> _class:basic_organization] map[_Id:4K7qx_mUnvB-----------== name:<name omitted> _class:basic_organization]]
我在这里真正的问题是,我有以下类型:
MyCustomStructA,
MyCustomeStructB
并且我用其中的任意一个来保全该功能,我如何才能在该循环中使用实际的结构项呢?因为在此刻,我会看到一张地图,而那不是我想要的。
答案 0 :(得分:0)
我建议使所有这些自定义类型都实现一个表示它们“可处理”的接口。然后,在ProcessSlice()
中,您可以遍历slice元素并处理实现Processable
接口的元素。像这样:
// Processable is a type that can be 'processed'
type Processable interface {
Process()
}
// ProcessSlice processes a slice of types that can be processed
func ProcessSlice(in interface{}) {
switch reflect.TypeOf(in).Kind() {
case reflect.Slice:
s := reflect.ValueOf(in)
for i := 0; i < s.Len(); i++ {
v := s.Index(i).Interface()
if p, ok := v.(Processable); ok {
p.Process()
}
}
}
}
通过这种方式,类型的所有处理逻辑都可以附加到类型本身,并且在添加新的自定义类型时也不需要修改ProcessSlice()
。
谈到实际问题,您可以像这样在slice值上使用类型开关(尽管我更喜欢使用接口方式)
// ProcessSliceConcreteTypes processes a slice of types based on the type of the slice
func ProcessSliceConcreteTypes(in interface{}) {
switch reflect.TypeOf(in).Kind() {
case reflect.Slice:
s := reflect.ValueOf(in)
switch sv := s.Interface().(type) {
case []S1:
for _, s1 := range sv {
s1.Process()
}
case []S2:
for _, s2 := range sv {
s2.Process()
}
default:
// error here
}
}
}
(在Go Playground上查看)