登录
首页 >  Golang >  Go问答

类型转换:切片与接口

来源:stackoverflow

时间:2024-02-16 12:18:23 319浏览 收藏

来到golang学习网的大家,相信都是编程学习爱好者,希望在这里学习Golang相关编程知识。下面本篇文章就来带大家聊聊《类型转换:切片与接口》,介绍一下,希望对大家的知识积累有所帮助,助力实战开发!

问题内容

如果我有一个传递 interface{} 的函数,我可以(通过其他方式)确定它是一个切片,但不能确定它是什么切片,那么我如何迭代它(最好不使用反射)?

这是一个 mcve(与我的实际代码相比非常简化)。 foreach 是一个迭代 a 切片的函数,其类型在 main() 的调用堆栈中“丢失”。它试图表达“啊哈,一个切片,我将迭代它的 interface{} 切片,并对每个值调用传入的 oneach 函数”。这会失败,因为类型“转换”失败,因此:

panic: interface conversion: interface {} is []string, not []interface {}

我非常清楚为什么类型“转换”失败,即它并不是真正的类型转换,而是一个断言。然而,考虑到(如果我可以迭代的话)我可以对每个切片成员进行断言,这原则上应该是可行的。

假设我实际上想要一个像 foreach 这样的迭代器,它可以做到这一点(而不是 foreachstringforeachint 等)。有没有好的方法可以做到这一点?最好没有反射(虽然我想这没关系),但肯定没有涉及每种类型的情况的反射(这就是首先拥有 foreach 函数的要点)?

我知道(尚未实现)泛型提案对此非常有效,但我想用现有技术来做到这一点!

package main

import (
    "fmt"
)

type onEach func(x interface{})

func printString(x interface{}) {
    xx := x.(string)
    fmt.Printf("x is a string '%s'\n", xx)
}

func printInt(x interface{}) {
    xx := x.(int)
    fmt.Printf("x is an int '%d'\n", xx)
}

func forEach(y interface{}, onEach onEach) {
    // code to ensure y is a slice omitted
    a := y.([]interface{}) // <-------- THIS LINE PANICS
    for _, x := range a {
        onEach(x)
    }
}

func main() {
    s := []string{"foo", "bar"}
    i := []int{1, 2, 3}
    forEach(s, printString)
    forEach(i, printInt)
}

解决方案


所以这是一个使用反射的答案,我想这并不太难看。

package main

import (
    "fmt"
    "reflect"
)

type onEach func(x interface{})

func printString(x interface{}) {
    xx := x.(string)
    fmt.Printf("x is a string '%s'\n", xx)
}

func printInt(x interface{}) {
    xx := x.(int)
    fmt.Printf("x is an int '%d'\n", xx)
}

func forEach(y interface{}, onEach onEach) {
    // code to ensure y is a slice omitted
    v := reflect.ValueOf(y)
    for i := 0; i < v.Len(); i++ {
        onEach(v.Index(i).Interface())
    }
}

func main() {
    s := []string{"foo", "bar"}
    i := []int{1, 2, 3}
    forEach(s, printString)
    forEach(i, printInt)
}

今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>