go - 拆分客户端/服务器代码

标签 go server client

我正在用golang开发客户端/服务器应用程序,客户端和服务器上都存在某些逻辑实体(列表有限)

我想确保这个实体的某些代码只包含在服务器部分而不是客户端(反之亦然很好,但并不那么重要)。

天真的想法是依靠死代码消除,但从我的简短研究来看,这不是处理任务的可靠方法...... go build 根本不会消除死代码事实上它可能是通过反射使用的(没有人关心它不是,也没有调整它的选项)

更可靠的方法似乎是将代码拆分到不同的包中并适本地导入,这似乎可靠但会使代码过于复杂,迫使您在不同的包之间物理拆分某些实体并始终牢记这一点...

最后还有构建标签,允许在同一个包下有条件地为客户端和服务器构建多个文件

使用构建标签的动机是我希望在不引入任何合成实体的情况下保持代码尽可能干净

用例: 有一定的密码学例程,客户端使用公钥工作,服务器使用私钥操作......代码在逻辑上属于同一个实体

您会选择什么选项,为什么?

最佳答案

go 工具已经部分完成了“死代码消除”。 go 工具不包括导入包中的所有内容,仅包括需要的内容(或更准确地说:它排除了可以证明无法访问的内容)。

例如这个应用

package main; import _ "fmt"; func main() {}

与以下相比,可执行二进制文件(在 windows amd64 上)小了近 300KB:

package main; import "fmt"; func main() {fmt.Println()}

可排除的东西包括函数、类型甚至未导出和导出的变量。这是可能的,因为即使使用反射,您也不能调用函数或“实例化”类型或仅通过将它们的名称作为 string 值来引用包变量。所以也许你不应该太担心它。

编辑随着 Go 1.7 的发布,它变得更好:阅读博文:Smaller Go 1.7 binaries

因此,如果您很好地设计了类型和函数,并且没有创建枚举函数和类型的“巨型”注册表(显式生成对它们的引用,从而使它们不可排他),编译后的二进制文件将仅包含实际上是从导入的包中使用的。

我不建议使用构建标签来解决这类问题。通过使用它们,您将有额外的责任自己维护包/文件依赖关系,否则由 go 工具完成。

您不应将代码设计和分离到包中以使输出的可执行文件更小。您应该根据逻辑将代码设计和分离到包中。

我会在真正需要的时候把东西分成包,然后适本地导入。因为这确实是您想要的:一些代码仅供客户端使用,一些仅供服务器使用。在设计和编码阶段,您可能需要多考虑一些,但至少您会看到结果(实际属于/被编译到客户端和服务器中的内容)。

关于go - 拆分客户端/服务器代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38875016/

相关文章:

go - 在 golang 中处理列表

go - 在 Go 中,如何跟踪哪个导入导致变量初始化时发生的错误?

Eclipse 语音浏览器/服务器插件

c - 在 Select 中阻止一个客户端而不阻止其他人

go - 如何检测按键事件

go - 如何使用 GORM 创建或更新记录?

c# - 当我从客户端向服务器发送命令时,仅当请求发送两次时,客户端才会收到响应

ubuntu - 在 Ubuntu 上启动时运行 Jupyter-notebook

python - 一个输出网站源代码的python套接字客户端,为什么不起作用?

java - 在 Java 中通过 TCP 发送 ArrayList<String[]> 的最佳方式?