英文:
Is there a nice way to get length of slice elem in map regardless of its concrete type?
问题
例如,我有两个映射,分别是 map[string][]structA
和 map[string][]int
。
我想要遍历这个映射并打印出每个切片的长度,我能在一个函数中实现这个吗?
我尝试定义一个接口,并在两种类型的切片中实现它,但是编译器无法进行类型转换。
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, length:%d", key, value.Len())
}
}
func main() {
// 无法进行类型转换
iterate(map[string]Slice1{})
iterate(map[string]Slice2{})
}
英文:
For example, I have two maps, namely map[string][]structA
and 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{})
}
答案1
得分: 1
你可以将这个功能实现在一个单独的函数中,但是调用函数的方式需要做一些改变。将你的映射转换为map[string]Container
,然后调用iterate
函数。
func main() {
// 无法进行类型转换
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)
}
输出:
2021/07/06 12:15:25 key:key, length:3
2021/07/06 12:15:25 key:key1, length:2
iterate
函数期望接收map[string]Container
类型的参数。因此,你可以使用Container
类型初始化它,并在映射的不同键中包含不同的Container
实现。
func main() {
// 无法进行类型转换
iterate(map[string]Container{
`ke1`: Slice1([]int{
1, 2, 3,
}),
`ke2`: Slice2([]StructA{
{},
{},
}),
})
}
输出:
2021/07/06 11:57:55 key:ke1, length:3
2021/07/06 11:57:55 key:ke2, length:2
英文:
"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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论