gswen
gswen

Reputation: 11

Is there a nice way to get length of slice elem in map regardless of its concrete type?

For example, I have two maps, namely map[string][]structAand map[string][]int.

I want to iterate the map and print out length of every slice, can I implement this in a single function?

I tried to define an interface and implement it in two kinds of slices, but the compiler just cannot do the type cast.

type Container interface{
    Len() int
}

type Slice1 []int
func (s Slice1) Len() int {
    return len(s)
}

type Slice2 []StructA
func (s Slice2) Len() int {
    return len(s)
}

func iterate(input map[string]Container) {
    for key, value := range input {
        log.Printf("key:%s, lenght:%d", key, value.Len())
    }
}

func main() {
    // cannot do the type cast
    iterate(map[string]Slice1{})
    iterate(map[string]Slice2{})
}

Upvotes: 0

Views: 222

Answers (1)

nipuna
nipuna

Reputation: 4095

"can I implement this in a single function?"

Yes, but the way you called the function should be changed. Convert your maps to map[string]Container and then call the iterate

func main() {
    // cannot do the type cast
    map1 := map[string][]int{
        `key`: []int{1,2,3},
    }

    map1Container := make(map[string]Container)
    for key, value := range map1 {
        map1Container[key] = Slice1(value)
    }

    map2 := map[string][]StructA{
        `key1`: []StructA{{}, {}},
    }
    map2Container := make(map[string]Container)
    for key, value := range map2 {
        map2Container[key] = Slice2(value)
    }

    iterate(map1Container)
    iterate(map2Container)
}

Output:

2021/07/06 12:15:25 key:key, lenght:3
2021/07/06 12:15:25 key:key1, lenght:2

iterate function expected map[string]Container type parameter. So you can initiate that with Container type and inside the map with different keys, you can include different Container's implementations.

func main() {
    // cannot do the type cast
    iterate(map[string]Container{
        `ke1`: Slice1([]int{
            1, 2, 3,
        }),
        `ke2`: Slice2([]StructA{
            {},
            {},
        }),
    })
}

Output:

2021/07/06 11:57:55 key:ke1, lenght:3
2021/07/06 11:57:55 key:ke2, lenght:2

Upvotes: 1

Related Questions