猿问

调用动态类型的接口方法

我正在尝试使用Go接口编写一个通用模块。这会导致错误:


panic: interface conversion: interface {} is main.AmazonOrder, not main.OrderMapper

法典:


package main


type 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


阿波罗的战车
浏览 130回答 1
1回答

阿晨1998

你必须使用界面,而不是带有函数字段的结构,我在恒河周围留下了评论。// 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}
随时随地看视频慕课网APP

相关分类

Go
我要回答