如何在Go中循环遍历不同类型?

时间:2013-08-24 09:14:25

标签: go range

在Go中,为了迭代数组/切片,你会写这样的东西:

for _, v := range arr {
    fmt.Println(v)
}

但是,我想迭代包含不同类型(int,float64,string等等)的数组/切片。在Python中,我可以按如下方式编写它:

a, b, c = 1, "str", 3.14
for i in [a, b, c]:
    print(i)

我怎样才能在Go做这样的工作?据我所知,数组和切片都应该只允许相同类型的对象,对吧? (例如,[]int仅允许int类型对象。)

感谢。

1 个答案:

答案 0 :(得分:5)

由于Go是一种静态类型语言,因此不像Python那么容易。你将不得不采用类型断言,反思或类似手段。

看一下这个例子:

package main

import (
    "fmt"
)

func main() {
    slice := make([]interface{}, 3)
    slice[0] = 1
    slice[1] = "hello"
    slice[2] = true

    for _, v := range slice {
        switch v.(type) {
        case string:
            fmt.Println("We have a string")
        case int:
            fmt.Println("That's an integer!")
            // You still need a type assertion, as v is of type interface{}
            fmt.Printf("Its value is actually %d\n", v.(int))
        default:
            fmt.Println("It's some other type")
        }
    }
}

这里我们构造一个具有空接口类型的切片(任何类型实现它),执行type switch并根据其结果处理该值。

不幸的是,在处理未指定类型的数组(空接口)的任何地方,你都需要这个(或类似的方法)。此外,除非您有办法处理任何可能的对象,否则您可能需要为每种可能的类型添加一个案例。

一种方法是使您想要存储的所有类型实现您的某些接口,然后仅通过该接口使用这些对象。这就是fmt处理泛型参数的方式 - 它只是在任何对象上调用String()来获取其字符串表示。