使用兼容接口进行Go恐慌界面转换

huangapple go评论75阅读模式
英文:

Go panic interface conversion with a compatible interface

问题

我遇到了一个无法解决的问题已经几个小时了。我需要从一个以太坊智能合约调用中解码数据(但这不是问题的重点,因为这部分已经正常工作),但我将这些数据恢复到一个interface{}中。

当我想要将这个空接口转换为一个可用的结构体时,我得到了以下错误信息:panic: interface conversion: interface {} is struct { SrcToken common.Address "json:\"srcToken\""; DstToken common.Address "json:\"dstToken\""; SrcReceiver common.Address "json:\"srcReceiver\""; DstReceiver common.Address "json:\"dstReceiver\&\quot;"; Amount *big.Int "json:\"amount\""; MinReturnAmount *big.Int "json:\"minReturnAmount\""; Flags *big.Int "json:\"flags\""; Permit []uint8 "json:\"permit\"" }, not oneinch.OneInchSwapDataDesc

结构体定义如下:

type OneInchSwapDataDesc struct {
	SrcToken        common.Address
	DstToken        common.Address
	SrcReceiver     common.Address
	DstReceiver     common.Address
	Amount          *big.Int
	MinReturnAmount *big.Int
	Flags           *big.Int
	Permit          []uint8
}

当我查看类型和数据值时,我得到了以下结果:

fmt.Println("Type: ", reflect.TypeOf(data))
fmt.Printf("Data: %+v\n", data)

// 输出:
// Type:  struct { SrcToken common.Address "json:\"srcToken\""; DstToken common.Address "json:\"dstToken\""; SrcReceiver common.Address "json:\"srcReceiver\""; DstReceiver common.Address "json:\"dstReceiver\""; Amount *big.Int "json:\"amount\""; MinReturnAmount *big.Int "json:\"minReturnAmount\""; Flags *big.Int "json:\"flags\""; Permit []uint8 "json:\"permit\"" }
// Data: {SrcToken:0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 DstToken:0xc2132D05D31c914a87C6611C10748AEb04B58e8F SrcReceiver:0x11431a89893025D2a48dCA4EddC396f8C8117187 DstReceiver:0x2C2d6E5E16FE924cE31784cdAd27C01D1BC62873 Amount:+10000000 MinReturnAmount:+9949450 Flags:+4 Permit:[]}

我认为这个问题可能来自于TypeOf返回的那些json字符串,但我找不到任何方法来清除它们(实际上,我不确定问题是否真的来自于这个)。

如果有人有任何想法,你将拯救我免于脑袋烧毁的地狱。谢谢。

英文:

I'm facing an unsupportable problem for hours, I have to decode data from an Ethereum smart contract call (but it's not the topic because this part work) but I recover theses data into an interface{}.

And when I want to cast this empty interface to a struct that I can use, I got this message : panic: interface conversion: interface {} is struct { SrcToken common.Address "json:\"srcToken\""; DstToken common.Address "json:\"dstToken\""; SrcReceiver common.Address "json:\"srcReceiver\""; DstReceiver common.Address "json:\"dstReceiver\""; Amount *big.Int "json:\"amount\""; MinReturnAmount *big.Int "json:\"minReturnAmount\""; Flags *big.Int "json:\"flags\""; Permit []uint8 "json:\"permit\"" }, not oneinch.OneInchSwapDataDesc

The struct is :

type OneInchSwapDataDesc struct {
	SrcToken        common.Address
	DstToken        common.Address
	SrcReceiver     common.Address
	DstReceiver     common.Address
	Amount          *big.Int
	MinReturnAmount *big.Int
	Flags           *big.Int
	Permit          []uint8
}

When I look for the type and the data value I got :

fmt.Println("Type: ", reflect.TypeOf(data))
fmt.Printf("Data: %+v\n", data)

// Logs:
// Type:  struct { SrcToken common.Address "json:\"srcToken\""; DstToken common.Address "json:\"dstToken\""; SrcReceiver common.Address "json:\"srcReceiver\""; DstReceiver common.Address "json:\"dstReceiver\""; Amount *big.Int "json:\"amount\""; MinReturnAmount *big.Int "json:\"minReturnAmount\""; Flags *big.Int "json:\"flags\""; Permit []uint8 "json:\"permit\"" }
// Data: {SrcToken:0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 DstToken:0xc2132D05D31c914a87C6611C10748AEb04B58e8F SrcReceiver:0x11431a89893025D2a48dCA4EddC396f8C8117187 DstReceiver:0x2C2d6E5E16FE924cE31784cdAd27C01D1BC62873 Amount:+10000000 MinReturnAmount:+9949450 Flags:+4 Permit:[]}

I think this problem come from those "json" that comes out from the TypeOf but I don;t find any tricks to clear it (in fact, I'm not really sure if the problem really come from that).

If someone have an idea, you'll save my brain from burning in hell.
Thanks.

答案1

得分: 1

接口的类型是struct { SrcToken ...}。它是一个无名类型。类型断言只有在类型完全相同的情况下才能起作用,或者断言的类型是一个接口,并且底层接口类型实现了该接口。你想要转换的类型不是一个接口,而是一个结构体。所以你可以这样做:

value := data.(struct { 
    SrcToken common.Address `json:"srcToken"`
    DstToken common.Address `json:"dstToken"`
    SrcReceiver common.Address `json:"srcReceiver"`
    DstReceiver common.Address `json:"dstReceiver"`
    Amount *big.Int `json:"amount"`
    MinReturnAmount *big.Int `json:"minReturnAmount"`
    Flags *big.Int `json:"flags"`
    Permit []uint8 `json:"permit"` })

一旦你有了这个,你可以使用以下方式将value转换为你想要的类型:

targetValue := oneinch.OneInchSwapDataDesc(value)
英文:

The interface has a value of type struct { SrcToken ...}. It is an unnamed type. Type assertion will only work if the types are identical, or if the asserted type is an interface and the underlying interface type implements that interface. The type you are trying to convert to is not an interface, but a struct. So you can do this:

value:=data.(struct { 
SrcToken common.Address `json:"srcToken"`
 DstToken common.Address `json:"dstToken"`
 SrcReceiver common.Address `json:"srcReceiver"`
 DstReceiver common.Address `json:"dstReceiver"`
 Amount *big.Int `json:"amount"`
 MinReturnAmount *big.Int `json:"minReturnAmount"`
 Flags *big.Int `json:"flags"`
 Permit []uint8 `json:"permit"` })

Once you have this, you can convert value to the type you want using:

targetValue:=oneinch.OneInchSwapDataDesc(value)

huangapple
  • 本文由 发表于 2021年9月20日 08:54:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/69248134.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定