gpt4 book ai didi

types - 迭代一个接口(interface)

转载 作者:IT王子 更新时间:2023-10-29 02:05:52 24 4
gpt4 key购买 nike

我想创建一个函数,它接受一个映射或一个数组,并迭代它,在每个项目上调用一个函数,该函数知道如何处理它遇到的任何类型。

这是我第一次失败的尝试。目前,当我在实际用例中运行它时,它总是说“呃哦!”。

func DoTheThingToAllTheThings(data_interface interface{}) int {
var numThings int

switch data := data_interface.(type) {
case map[interface{}]interface{}:
numThings = len(data)
for index, item := range data {
DoTheThing(index, item)
}
case []interface{}:
numThings = len(data)
for index, item := range data {
DoTheThing(index, item)
}
default:
fmt.Println("uh oh!")
}

return numThings
}

数组或映射可能包含很多不同的东西,因此无法尝试匹配所有可能的输入。

换句话说,有没有办法在 Go 中迭代一个数组或映射而不知道它到底是什么?

最佳答案

函数 fmt.Printf("%v\n", data_interface) 完全符合您的要求。它将打印传递给它的整个映射或数组。

您可以在此处找到实现:http://golang.org/src/pkg/fmt/print.go?h=printArg#L708

printArg 结尾附近的行是关键:

return p.printReflectValue(reflect.ValueOf(arg), verb, plus, goSyntax, depth

它使用“反射”包:http://golang.org/pkg/reflect/查询参数的类型。在 p.printReflectValue 中:http://golang.org/src/pkg/fmt/print.go?h=printArg#L862您将看到处理 map 和结构的两种情况。然后它通过 printValue 使用递归来管理内容。

下面是一段代码,它获取结构的反射,然后将其转换回正确类型的另一个变量。您不能使用它从一种任意类型更改为另一种类型,在不使用反射的情况下将类型从一种类型转换为另一种类型必须是合法的。

package main

import (
"fmt"
"reflect"
)

type Player string

type Board struct {
Tboard [9]string
Player1 Player
Player2 Player
}

// ignore this function contents, I grabbed it from elsewhere.
func makeBoard() *Board {
b := &Board{Tboard: [9]string{}}
for x := 0; x < len(b.Tboard); x++ {
b.Tboard[x] = "X"
fmt.Println(b.Tboard[x])
}
b.Player1 = "George"
b.Player2 = "Tim"

fmt.Printf("Len: %v\n", len(b.Tboard)) // => 9

fmt.Printf("Contents: %v\n", b)
fmt.Printf("Syntax: %#v\n", b)
fmt.Printf("Type: %T\n", b)
fmt.Println("Board:", b.Tboard)
return b
}

func main() {
myBoard := makeBoard()

v := reflect.ValueOf(*myBoard) // v is of type Value
t := v.Type()

fmt.Printf("Value: %v %T\n", v, v)
fmt.Printf("Type: %v %T\n", t, t)

// would be a switch
if t == reflect.TypeOf(*myBoard) {
var b2 Board

b2 = v.Interface().(Board) // cast the type interface{} into type Board
fmt.Printf("v converted back to: %#v\n", b2)
} else {
fmt.Printf("t is not recognized")
}

}

注意v的类型是main.Board,是完整的包名,不是Board。您想要对其执行此操作的任何结构都必须具有导出类型才能使反射起作用。

关于types - 迭代一个接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25821708/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com