脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - Go Struct 初始化风格的抉择

Go Struct 初始化风格的抉择

2020-11-23 22:39MohuishouMohuishou Golang

最近在对之前的代码做重构,从之前的 MVC 结构切换到 Clean Arch 的结构,但是在切换的时候关于代码风格出现了一些困惑。

最近在对之前的代码做重构,从之前的 MVC 结构切换到 Clean Arch 的结构,但是在切换的时候关于代码风格出现了一些困惑。

在下面的代码中 repository 是存储库,主要用于封装数据库查询或者是第三方微服务的调用,它实现了 domain.IAzRepository 接口,其他层的代码都只依赖这个接口而不依赖具体的实现

Go Struct 初始化风格的抉择

三种代码风格

风格一

在 Go 中我们常常“返回实现(struct),依赖接口”,其实就是在函数返回的时候我们返回一个具体的实现,函数的参数或者是 Struct 的成员部分我们依赖接口,这个风格看起来是违背了这个原则的

// repository 存储库 

type repository struct { 

    db *gorm.DB 

 

// NewAZRepository NewAZRepository 

func NewAZRepository(db *gorm.DB) domain.IAzRepository { 

    return &repository{db: db} 

风格二

这个风格返回了实现,并且由于并没有导出看起来也具有封装的特性,但是如果你运行 golint 你就会发现会抛出错误,因为这么写,会导致我们用导出的方法将没有导出 struct 给暴露了出去

// repository 存储库 

type repository struct { 

    db *gorm.DB 

 

// NewAZRepository NewAZRepository 

func NewAZRepository(db *gorm.DB) *repository { 

    return &repository{db: db} 

风格三

这个写法的主要问题是,由于 Repository 被导出,所以在外部其他的包中就可以直接通过 &Repository{} 进行初始化,这样初始化之后使用就会导致 panic,因为成员函数是一个 nil 指针

// Repository 存储库 

type Repository struct { 

    db *gorm.DB 

 

// NewAZRepository NewAZRepository 

func NewAZRepository(db *gorm.DB) *Repository { 

    return &Repository{db: db} 

选择

选择总是困难的,带着这个问题我咨询了同组的同事还有好几个 Go 语言交流群的同学,其中大部分都会选择风格三,小部分会选择风格一,风格二几乎没有人选择。最后我选什么呢?

最后我的选择是风格一,这是针对场景来的,因为我们的这个包其实不希望其他包直接依赖实现,因为后续有可能随着发展被单独拆分成一个微服务或者是需要更换存储库,如果外部有包直接依赖 repository 会导致后续的重构比较困难

除此之外,我们在其他地方一般还是会选择风格三,因为结构体名不导出,外部其实没有比较好的办法进行初始化,例如想要 var r Repository ,至于前面提到的直接字面量初始化的问题,我们可以通过统一代码风格解决。

在 外部包 中除了用于参数传递的 Option 结构之外,其余的不允许直接通过 &XXX{} 的方式进行初始化

原文地址:https://lailin.xyz/post/go-new-struct-style-select.html?utm_source=tuicool&utm_medium=referral

延伸 · 阅读

精彩推荐
  • GolangGolang通脉之数据类型详情

    Golang通脉之数据类型详情

    这篇文章主要介绍了Golang通脉之数据类型,在编程语言中标识符就是定义的具有某种意义的词,比如变量名、常量名、函数名等等,Go语言中标识符允许由...

    4272021-11-24
  • Golanggo日志系统logrus显示文件和行号的操作

    go日志系统logrus显示文件和行号的操作

    这篇文章主要介绍了go日志系统logrus显示文件和行号的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    SmallQinYan12302021-02-02
  • Golanggolang的httpserver优雅重启方法详解

    golang的httpserver优雅重启方法详解

    这篇文章主要给大家介绍了关于golang的httpserver优雅重启的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    helight2992020-05-14
  • Golanggolang json.Marshal 特殊html字符被转义的解决方法

    golang json.Marshal 特殊html字符被转义的解决方法

    今天小编就为大家分享一篇golang json.Marshal 特殊html字符被转义的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 ...

    李浩的life12792020-05-27
  • GolangGolang中Bit数组的实现方式

    Golang中Bit数组的实现方式

    这篇文章主要介绍了Golang中Bit数组的实现方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    天易独尊11682021-06-09
  • Golanggo语言制作端口扫描器

    go语言制作端口扫描器

    本文给大家分享的是使用go语言编写的TCP端口扫描器,可以选择IP范围,扫描的端口,以及多线程,有需要的小伙伴可以参考下。 ...

    脚本之家3642020-04-25
  • Golanggolang如何使用struct的tag属性的详细介绍

    golang如何使用struct的tag属性的详细介绍

    这篇文章主要介绍了golang如何使用struct的tag属性的详细介绍,从例子说起,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看...

    Go语言中文网11352020-05-21
  • Golanggolang 通过ssh代理连接mysql的操作

    golang 通过ssh代理连接mysql的操作

    这篇文章主要介绍了golang 通过ssh代理连接mysql的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    a165861639710342021-03-08