如何将字节切片优雅地解码为不同的结构

var response Response

switch wrapper.Domain {

case "":

    response = new(TypeA)

case "TypeB":

    response = new(TypeB)

case "TypeC":

    response = new(TypeC)

case "TypeD":

    response = new(TypeD)

}

_ = decoder.Decode(response)

如代码片段所示,我从 的字段中获得了足够的信息来确定响应的类型,并且对于每种类型,都执行以下操作:Domainwrapper


使用创建该类型的新实例new

使用解码器将字节切片解码为在步骤1中创建的实例,我想知道是否有办法使第一步更加通用并摆脱switch语句。


繁星coding
浏览 98回答 1
1回答

翻过高山走不出你

关于您的代码的一些内容根据评论中的讨论,我想分享一些经验。我没有看到你的解决方案有什么不好的,但是改进它的选项很少,这取决于你想做什么。你的代码看起来像经典的工厂。这是一种模式,它基于一些输入参数创建单个族的对象。Factory在Golang中,这通常以更简单的方式用作,有时称为。Factory MethodFactory function例:type Vehicle interface {};type Car struct {}func NewCar() Vehicle {&nbsp; &nbsp;return &Car{}}但是您可以轻松扩展它以执行类似您的操作:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "strings")type Vehicle interface {}type Car struct {}type Bike struct {}type Motorbike struct {}// NewDrivingLicenseCar returns a car for a user, to perform&nbsp;// the driving license exam.func NewDrivingLicenseCar(drivingLicense string) (Vehicle, error) {&nbsp; &nbsp; switch strings.ToLower(drivingLicense) {&nbsp; &nbsp; case "car":&nbsp; &nbsp; &nbsp; &nbsp; return &Car{}, nil&nbsp; &nbsp; case "motorbike":&nbsp; &nbsp; &nbsp; &nbsp; return &Motorbike{}, nil&nbsp; &nbsp; case "bike":&nbsp; &nbsp; &nbsp; &nbsp; return &Bike{}, nil&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; return nil, fmt.Errorf("Sorry, We are not allowed to make exam for your type of car: \"%s\"", drivingLicense)&nbsp; &nbsp; }}func main() {&nbsp; &nbsp; fmt.Println(NewDrivingLicenseCar("Car"))&nbsp; &nbsp; fmt.Println(NewDrivingLicenseCar("Tank"))}上面的代码产生输出:&{} <nil><nil> Sorry, We are not allowed to make exam for your type of car: "Tank"因此,也许您可以通过以下方式改进代码:关闭到单个函数中,该函数采用 a 并生成stringResponse object添加一些验证和错误处理给它一些合理的名字。与工厂相关的模式很少,可以替换此模式:责任链调度游客依赖注入反射?@icza也有关于反射的评论。我同意他的观点,这是常用的,我们无法避免代码中的反射,因为有时事情是如此动态。但在你的场景中,这是一个糟糕的解决方案,因为:您丢失了编译时类型检查添加新类型时必须修改代码,那么为什么不在此 Factory 函数中添加新行呢?你使代码变慢(参见参考),它增加了50%-100%的性能损失。你让你的代码如此不可读和复杂您必须添加更多的错误处理,以涵盖反射带来的不小错误。当然,您可以添加大量测试来涵盖大量场景。您可以在代码中支持 、,并且可以使用测试来覆盖它,但是在生产代码中,有时您可以通过,如果不捕获它,您将收到运行时错误。TypeATypeBTypeCTypeXYZ结论你的方案没有什么不好的,这可能是做你想做的事情的最容易读和最简单的方法。switch/case参考工厂方法:https://www.sohamkamani.com/golang/2018-06-20-golang-factory-patterns/关于编程模式的经典书籍:设计模式:可重用面向对象软件的元素,ISBN:978-0201633610Erich Gamma and his band of four反射基准:https://gist.github.com/crast/61779d00db7bfaa894c70d7693cee505
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go