でそれを使用するために、私はからreflect.Selectの例を取りました。しかし、それは単純な "chan"からreflect.Value()を作成していました:= make(chan int)setup。どのインターフェースからちゃん値を取得し、reflect.Select(...)
しかし、インタフェース{}として渡された構造体のチャネルを使用したかったのです。
私は構造体を作成し、それを処理のためにインターフェイスパラメータ として渡すようにプログラムを修正しました。
実行すると、私が手:パニック:反映します。struct Valuepanic上reflect.Value.Elemの呼び出し:反映します。struct値にreflect.Value.Elemの呼び出しを
これは奇妙であるI正確なコード理由動作する別のプログラム!
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
}
いかなる 体は、私は単純な変数バージョンで置き換えるには、インタフェースコード を使用しようとして間違ったつもりどこを教えてもらえます。
プログラムは、変化を示すコメントを以下の通りです:これを行うには
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++
}
}
}
エラーメッセージが伝えました。 –