我正在尝试动态设计一个协议测试。
我需要使用的函数是go-ethereum的Decode
:https://github.com/ethereum/go-ethereum/blob/master/p2p/message.go#L54
然后我的一些代码使用它:
msg <- receive() //sends me a message of type p2p.Msg
var message MyTargetType
msg.Decode(&message) // this works correctly and this is apparently the correct way to use the function, with a pointer to the variable
anotherMessage := output.Msg // this is an interface{}, see below
msg.Decode(&anotherMessage) // this fails
我不明白为什么Decode
方法处理这两个不同。一个小测试程序:
package main
import (
"fmt"
"reflect"
)
type mystruct struct {
hello string
}
func main() {
var first mystruct
second := mystruct{}
fmt.Println(reflect.TypeOf(first))
fmt.Println(reflect.TypeOf(second))
}
这将打印相同的类型:
main.mystruct
main.mystruct
但不知何故,上面的Decode
,在内部使用反射,处理它们的方式不同。
我的问题是什么?对于我的协议测试,我想定义预期的输出类型:
type Output struct {
Msg interface{}
}
由于消息可以是非常不同的类型,我认为唯一的方法是使用interface{}
。因此:
output := Output{
Msg: MyTargetType{}.
}
//
anotherOutput := Output{
Msg: AnotherType{}.
}
// and so on
这样我以后就可以检查接收到的输出是否是预期的输出。但是那个Decode
方法快把我逼疯了。
我已经尝试了几件事与反思,例如。
var decodedMsg = reflect.TypeOf(output.Msg)
msg.Decode(&decodedMsg)
甚至
var decodedMsg = reflect.New(reflect.TypeOf(output.Msg)).Elem().Interface()
fmt.Println(reflect.TypeOf(decodedMsg)) //this actually prints the correct type!!!
// But then Decode fails nonetheless with:
// interface given to Decode must be a pointer
1条答案
按热度按时间vom3gejh1#
Decode的参数必须是指向目标类型的指针。使用以下代码:
使用reflect API处理任何类型: