【问题标题】:How to iterate over different types in loop in Go?如何在 Go 的循环中迭代不同的类型?
【发布时间】:2023-03-29 18:21:01
【问题描述】:

在 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 类型的对象。)

谢谢。

【问题讨论】:

    标签: go range


    【解决方案1】:

    由于 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() 以获取其字符串表示形式。

    【讨论】:

    • 由于我只需要打印每个变量,我想我不必使用 switch/case 而是只需在循环内输入fmt.Println(v),我可以轻松接受。非常感谢。
    • 是的,这正是我在上一段中提到的情况:类型实现了Stringer 接口,所以fmt.Println(v) 只需调用v.String(),甚至不需要知道确切的类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多