英文:
Is it recommended to keep a program sources (as opposed to lib sources) in a single file?
问题
我正在进入Go语言的学习阶段,显然我是根据我在其他语言中的经验来推理,而不是理解Go的特殊性和风格。
我决定重写一个在执行过程中需要很长时间的Ruby后台作业。它遍历我的数据库中的一个巨大表,并为每一行单独处理数据,因此它是一个很好的并行化候选。
作为一个使用ORM的Ruby on Rails任务,我认为这将是一个相当简单的两个文件程序:一个包含一个结构类型及其方法以表示和处理行的文件,以及用于操作数据库查询和循环行的主文件(如果在我的主文件中变得太重,可能还有一个抽象数据库访问逻辑的第三个文件)。我打算将这种文件分离方式用于代码库的清晰性,而不是在最终的二进制文件中具有任何相关性。
我已经阅读了关于这个主题的一些资料(链接1、链接2),包括这里的问题和答案,它们总是倾向于将代码编写为库,安装它们,然后在一个单一的文件源程序中使用它们(在main
包中)。
我读到过可以将多个文件传递给go build/run,但如果有多个包名,它会报错(所以基本上,所有的东西都应该在main
中),而且这似乎并不常见。
所以,我的问题是:
- 我理解得对吗?将代码主要作为一个库,然后通过导入它的方式在单一文件程序中使用它是正确的方法吗?
- 如果是这样,你是如何处理需要反复构建库的情况的?在每次更改库代码之前构建/安装它们(这比
go run
承诺的方便得多),还是有一些常见的方法可以在开发这些库的代码时快速执行依赖于库的程序?
英文:
I am making my first steps into Go and obviously am reasoning from what I'm used to in other languages rather than understanding go specificity and styles yet.
I've decided to rewrite a ruby background job I have that takes ages to execute. It iterates over a huge table in my database and process data individually for each row, so it's a good candidate for parallelization.
Coming from a ruby on rails task and using ORM, this was meant to be, as I thought of it, a quite simple two files program: one that would contain a struct type and its methods to represent and work with a row and the main file to operate the database query and loop on rows (maybe a third file to abstract database access logic if it gets too heavy in my main file). This file separation as I intended it was meant for codebase clarity more than having any relevance in the final binary.
I've read and seen several things on the topic, including questions and answers here, and it always tends to resolve into writing code as libraries, installing them and then using them into a single file source (in package main) program.
I've read that one may pass multiple files to go build/run, but it complains if there is several package name (so basically, everything should be in main
) and it doesn't seem that common.
So, my questions are :
- did I get it right, and having code mostly as a library with a single file program importing it the way to go?
- if so, how do you deal with having to build libraries repeatedly? Do you build/install on each change in library codebase before executing (which is way less convenient that what
go run
promise to be) or is there something common I don't know of to execute library dependent program quick and fast while working on those libraries code?
答案1
得分: 10
不。
Go和go
工具仅适用于包(只有go run
适用于文件,但那是另一回事):在组织Go代码时,你不应该考虑文件,而是包。一个包可以分成多个文件,但这是为了保持测试代码的分离,限制文件大小或者对类型、方法、函数等进行分组。
你的问题:
> 我理解得对吗?将代码大部分作为库,然后通过导入的方式来编写单文件程序?
不一定。有时这样做有优势,有时没有。有时拆分可能是一个库+一个简短的主程序,而在其他情况下,只有一个大型主程序可能更好。再次强调:这一切都与包有关,而与文件无关。如果这是一个真正的独立程序,一个包含12个文件的主包没有任何问题。但是,将一些内容提取到一个或几个其他包中可能会导致代码更易读。这完全取决于具体情况。
> 如果是这样,那么在重复构建库时该如何处理?在每次更改库代码之前构建/安装,然后执行(这比go run承诺的方便得多),还是有一些常见的方法可以在开发这些库代码时快速执行依赖于库的程序?
go
工具会跟踪依赖关系并重新编译必要的内容。假设你有一个main.go
文件中的main包,它导入了一个名为foo的包。如果你执行go run main.go
,它会在需要时透明地重新编译foo包。因此,对于快速的修改:不需要两步go install foo; go run main
。一旦你将代码提取到foo、bar和waz三个包中,安装foo、bar和waz可能会更快一些。
英文:
No.
Go and the go
tool works on packages only (just go run
works on files, but that is a different story): You should not think about files when organizing Go code but packages. A package may be split into several files, but that is used for keeping test code separated and limiting file size or
grouping types, methods, functions, etc.
Your questions:
> did I get it right, and having code mostly as a library with a single file program
> importing it the way to go?
No. Sometimes this has advantages, sometimes not. Sometimes a split may be one lib + one short main,
in other cases, just one large main might be better. Again: It is all about packages and never about files. There is nothing wrong with a single 12 file main package if this is a real standalone program. But maybe extracting some stuff into one or a few other packages might result in more readable code. It all depends.
> if so, how do you deal with having to build libraries repeatedly? Do you build/install on each change in library codebase before executing (which is way less convenient that what go run promise to be) or is there something common I don't know of to execute library dependent program quick and fast while working on those libraries code?
The go
tool tracks the dependencies and recompiles whatever is necessary. Say you have a package main in main.go
which imports a package foo. If you execute go run main.go
it will recompile package foo transparently iff needed. So for quick hacks: No need for a two-step go install foo; go run main
. Once you extract code into three packages foo, bar, and waz it might be a bit faster to install foo, bar and waz.
答案2
得分: 2
不。查看Go命令和Go标准包以获取良好编程风格的示例。
英文:
No. Look at the Go commands and Go standard packages for exemplars of good programming style.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论