gpt4 book ai didi

go - 如何从接口(interface)获取 chan 值并在 reflect.Select(...) 中使用它

转载 作者:数据小太阳 更新时间:2023-10-29 03:35:35 25 4
gpt4 key购买 nike

我举了一个反射的例子。选择自: <强> https://www.socketloop.com/references/golang-reflect-select-and-selectcase-function-example

它会尽其所能。但它是从一个简单的创建 reflect.Value()“chan”:= make(chan int)设置。

但我想使用来自作为接口(interface)传递的结构的 channel {}。

所以我修改了程序以创建一个结构并将其传递给处理接口(interface)参数。

运行时我得到:panic: reflect: call of reflect.Value.Elem on struct Valuepanic: reflect: call of reflect.Value.Elem on struct Value

这很奇怪,因为我准确编码了​​另一个有效的程序!!

func inspect(f interface{}) map[string]string {

m := make(map[string]string)
val := reflect.ValueOf(f).Elem()

for i := 0; i < val.NumField(); i++ {
valueField := val.Field(i)
typeField := val.Type().Field(i)
f := valueField.Interface()

val := reflect.ValueOf(f)
m[typeField.Name] = val.String()
}

return m
}

可以任意body 告诉我尝试使用界面代码哪里出错了取代简单的变量版本。

程序如下,注释显示更改:

package main

// Original Example from:
// https://www.socketloop.com/references/golang-reflect-select-and-selectcase-function-example
//
import (
"fmt"
"reflect"
)

func main() {

// following replaces " var sendCh := make(chan int) "
type Foo struct {
Ch chan int
}
sendCh := Foo{make(chan int)}
// End of replacement code

var increaseInt = func(c chan int) {
for i := 0; i < 8; i++ {
c <- i
}
close(c)
}

go increaseInt(sendCh.Ch)

// This routine call replaces the code incorporated in "runJob"
// It was done so I could call through an empty interface{}
runJob(sendCh)
// End replaement code--
}

func runJob(f interface{}) {
var selectCase = make([]reflect.SelectCase, 1)

// This code replaces just using the orginal "sendCh" value
// I am trying here to construct "sendCh" from the interface value
val := reflect.ValueOf(f).Elem()
valueField := val.Field(0)
sendCh := valueField.Interface()
// End of replacement code

selectCase[0].Dir = reflect.SelectRecv
selectCase[0].Chan = reflect.ValueOf(sendCh)

counter := 0
for counter < 1 {
chosen, recv, recvOk := reflect.Select(selectCase) // <--- here
if recvOk {
fmt.Println(chosen, recv.Int(), recvOk)

} else {
fmt.Println("Exit Condition Detected: ", chosen, recv.Int(), recvOk)
counter++
}
}
}

最佳答案

一种方法是不进行反射,而是进行类型断言。所以你可以说:

val, ok := f.(Foo)
if !ok {
fmt.Printf("Not Foo? Try Bar.\n")
}
sendCh := val.Ch

或者,如果您坚持使用 reflect(这是一个较差的解决方案),您可以通过删除 Elem() 来获得您想要的结果。例如:

val := reflect.ValueOf(f)
valueField := val.FieldByName("Ch")
sendCh := valueField.Interface()

如果您不想使用该名称,甚至可以使用 val.Field(0)。同样,类型断言方法比这更好。

关于go - 如何从接口(interface)获取 chan 值并在 reflect.Select(...) 中使用它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37847463/

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