I'm trying to write a common module using Go interface. It results in an error:
panic: interface conversion: interface {} is main.AmazonOrder, not main.OrderMapper
Code:
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)
}
In plain sight logic, this should work fine. But, definitely I'm misunderstanding the type conversion in Go. TIA for clarifying what it is.
Playground: https://play.golang.org/p/tHCzKGzEloL
you have to use interface, not a struct with function field, i left comments around the ganges.
// 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
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.