为了账号安全,请及时绑定邮箱和手机立即绑定

调用动态类型的接口方法

调用动态类型的接口方法

Go
阿波罗的战车 2022-08-09 16:57:40
我正在尝试使用Go接口编写一个通用模块。这会导致错误:panic: interface conversion: interface {} is main.AmazonOrder, not main.OrderMapper法典:package maintype AmazonOrder struct {    OrderId string    ASIN string}func (o AmazonOrder) Generalise() *Order {    return &Order{        ChannelOrderId: o.OrderId,    }}type EbayOrder struct {    OrderId string    SKU string}func (o EbayOrder) Generalise() *Order {    return &Order{        ChannelOrderId: o.OrderId,    }}type Order struct {    ID string    ChannelOrderId string}type OrderMapper struct {    Generalise func() *Order}var orderFactory = map[string]func() interface{} {    "amazon": func() interface{} {        return AmazonOrder{}    },    "ebay": func() interface{} {        return EbayOrder{}    },    "vanilla": func() interface{} {        return Order{}    },}func main() {    orderType := "amazon"    initialiseOrder := orderFactory[orderType]    anOrder := initialiseOrder()    // Unmarshal from json into anOrder etc.. here.    theOrder := anOrder.(OrderMapper).Generalise()    println(theOrder.ChannelOrderId)}在简单的视线逻辑中,这应该工作正常。但是,我肯定误解了Go中的类型转换。TIA用于澄清它是什么。游乐场: https://play.golang.org/p/tHCzKGzEloL
查看完整描述

1 回答

?
阿晨1998

TA贡献2037条经验 获得超6个赞

你必须使用界面,而不是带有函数字段的结构,我在恒河周围留下了评论。


// OrderMapper is probably ment to be an interface. You can convert interface

// to struct only if its the original one. Though you need to convert it into iterface in 

// your case because type of return value is variable. As all orders implement 

// 'Generalise' and you are planing to convert empty interface to OderMapper why not just 

// return order mapper right away? also best practice to name your interface, with just 

// one method, is methodName + 'er' so Generalizer.

type OrderMapper interface {

    Generalise() *Order

}


/* alternative

    var orderFactory = map[string]func() OrderMapper{

    "amazon": func() OrderMapper {

        return AmazonOrder{OrderId: "amazonOrderID"}

    },

    "ebay": func() OrderMapper {

        return EbayOrder{}

    },

    "vanilla": func() OrderMapper {

        return Order{}

    },

}

*/

var orderFactory = map[string]func() interface{}{

    "amazon": func() interface{} {

        return AmazonOrder{OrderId: "amazonOrderID"} // i added a value to verify correctness

    },

    "ebay": func() interface{} {

        return EbayOrder{}

    },

    "vanilla": func() interface{} {

        return Order{}

    },

}


func main() {

    orderType := "amazon"


    initialiseOrder := orderFactory[orderType]

    anOrder := initialiseOrder()


    // Unmarshal from json into anOrder etc.. here.


    // alternative: theOrder := anOrder.Generalise()

    theOrder := anOrder.(OrderMapper).Generalise()


    println(theOrder.ChannelOrderId == "amazonOrderID") // true

}


查看完整回答
反对 回复 2022-08-09
  • 1 回答
  • 0 关注
  • 129 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信