暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

go 目录布局

原创 江右布衣 2023-11-01
105

作者:Golang发烧友
链接:https://zhuanlan.zhihu.com/p/585336701
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

1. 项目结构

无论是大项目还是小管理系统,万里长征第一步,都是如何组织自己的项目结构。在项目结构这方面,go其实没有一个固定的准则,因此可以根据实际情况,灵活的组织。但我觉得,还是需要知道一些需要注意的点:

1. 包名简单,但要注意见名知意

这点在这篇文章中已经提到过了,用精炼的缩写代替冗长的包名,并且go中也经常出现fmtstrconv等常用缩写包,还有pkgcmd等。但是我觉得,相比于简单,见名知意更重要。举个例子,我曾接手一个项目,它的根目录下就有一个mdw包,我开始还不知道这是干嘛的,看到里面放着一些 gin 的中间件才知道原来是middleware的缩写。所以尽管go官方是推荐用一些约定俗成的、简洁的包名,但是应该要加个前提,那就是在注释中说明一下本包的作用,而注释却是在国内环境中,非常缺少的。所以与其生造一些缩写,又不写注释,那还不如把包名写的清楚一些。

2. 使用 internal

使用 internal 有助于强制人思考,什么应该放在公共包,什么应该放在私有包,从而是项目结构更加清晰。而且go本身提供的包访问权限没有java那么详细,只有公开和私有这两种状态,更应该用internal来补充一下。

3. 不要随便使用 init

说实话,我对为什么没有对init做任何限制还是有些疑虑的,这也就是说,你依赖的某些库可以先于你的程序代码运行,你也不知道它会做什么事(任何代码都可以在init中执行)。这在那种依赖非常多,又有很多间接依赖的大型项目中体现的很明显。

尽管go官方要求不要在init中执行任何复杂的逻辑,但是这没有任何约束力。最简单的例子就是单元测试,我有时候跑单元测试经常会碰到panic跑不起来,究其原因就是某些依赖库init中做了一些骚操作。但问题是:我是依赖的依赖(间接依赖)了这个库,我也没法控制它的代码(没有修改权限)。

碰到这种情况,也只能在单元测试中完成它的要求才能继续运行。所以把代码放在init中,一定要三思。就我来看,很多用init的代码确实在做初始化,但它们内部隐式依赖了文件、路径、资源等。这种情况要想一想,是不是可以用 NewXX() \ InitXX() 这种函数来替代。

4. 慎用 util \ common 这种包名

这种一般是java程序员转过来的用的比较多,但其实在go中,是推荐有意义的包名来替代这种无意义的包名的。比如:util.NewTimeHelper() 就不好,应该写成time_helper.New() 这样可读性强一点。但是我觉得具体情况还得具体分析,所以标题是慎用,而不是不用。因为有些时候,你的 util \ common 也就几个帮助函数,没多少东西。再细分成几个包感觉有点得不偿失了,等util \ common 再攒多一点再重构也不迟。所以还是回到开头提到的,多思考,灵活处理。但是这里又要注意了,如果是那种被很多人依赖的公共 util \ common,最好还是早点拆分,不然后期可能拆不动了。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论