Golang核心概念验证指南
Golang核心概念验证指南 想要验证一些 Go 语言的概念
-
构建 Go 代码 获取他人的代码。让你的代码依赖于他人的代码。创建一个构建。这个构建会生成一个可移植的二进制文件——我可以在我的 Mac 上构建,但构建出的文件可以在 Windows/Linux/任何操作系统上运行,无需修改。 与 Java 和 NodeJs 比较。 代码导入的工作方式类似于 NodeJs,而不同于 Java。 可移植二进制文件的创建方式类似于 Java,而不同于 NodeJs。
-
二进制文件的使用 由于这种语言会生成二进制文件,因此与 Java 进行比较。 在 Java 中——作为开发者,我可以获取他人的 jar 文件(该 jar 文件必须是专门为此目的构建的)并在我的代码中导入其公开的方法/函数。他人的代码(源代码)对我不可见,因此他们是安全的,而我只能使用其他开发者公开的内容。 在 Go 中,我无法从我的代码中导入二进制文件公开的方法/函数。如果我的代码依赖于以下项目 A B C D E,我必须明确地依赖于每个项目的源代码。如果我想在我的代码中利用它们的功能,它们的每个可执行文件都是无用的。
-
包导入与契约 契约——以类类型的形式——对开发者来说一直很重要。其理念是:作为开发者,我定义我可以处理的内容。任何其他开发者导入我的代码时,将只能“看到”和“使用”我选择或允许他们看到或使用的内容。 作为 Go 开发者,我可以定义契约,但我无法限制其他开发者导入我的代码时仅使用我定义的契约。导入的开发者可以导入我的包中公开的任何其他代码。
更多关于Golang核心概念验证指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html
- 我不太确定你在这段话中提及 Java 和 JavaScript 的意图,但一个 Go 可执行文件只能在其编译时所针对的架构/操作系统上运行。为 Mac 编译的二进制文件无法在 Windows 上运行,反之亦然。关于如何进行交叉编译,请查阅
GOOS和GOARCH的文档。 - 二进制文件仅针对可执行文件创建。库文件会根据需要在编译时处理,并以静态链接的方式集成到你的二进制文件中。Go 的这种工作方式,基本上允许你部署闭源的可执行文件,但库文件必须对目标用户开源。
- 你可以使用
INTERNAL包,这至少可以使其子包无法被导入。不过,如前所述,代码对你的目标用户始终是可见的,因此他们可以直接复制粘贴实现。
仅包含二进制文件的包(这曾允许你创建闭源库)在早些时候是可行的,但据我回忆,在 Go 1.12 中已被弃用或移除。
更多关于Golang核心概念验证指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
1. 构建 Go 代码的可移植二进制文件
Go 通过静态编译生成可移植的二进制文件,依赖的代码会直接编译到二进制文件中。以下示例展示了如何构建跨平台二进制文件:
// main.go
package main
import (
"fmt"
"github.com/gorilla/mux" // 依赖外部包
)
func main() {
fmt.Println("可移植二进制示例")
}
构建命令(在 Mac 上构建 Linux 可执行文件):
GOOS=linux GOARCH=amd64 go build -o myapp-linux main.go
- 与 Java 比较:Java 生成字节码(.class/.jar),依赖 JVM 运行;Go 直接生成静态链接的二进制文件,无需运行时环境。
- 与 Node.js 比较:Node.js 需要源码和 node_modules,Go 将所有依赖编译到单个二进制文件中。
2. 二进制文件的依赖导入机制
Go 无法直接导入二进制文件中的方法,必须依赖源代码。示例:
// 依赖项目 A 的源代码(假设路径为 ./pkgA)
import "./pkgA"
func main() {
pkgA.PublicFunction() // 只能使用公开的源代码函数
}
- 与 Java 比较:Java 可以导入已编译的 .jar 文件(如
import com.example.Library;),Go 必须通过go.mod引用源代码仓库(如module github.com/user/repo)。 - 关键区别:Go 的依赖管理(go.mod)始终指向源代码,编译时拉取并编译源码,而非预编译的二进制库。
3. 包导入的可见性控制
Go 通过标识符首字母大小写控制可见性,但无法限制导入者访问包内的所有公开内容。示例:
// 包 mypkg 的代码
package mypkg
// 公开接口(契约)
type MyContract interface {
DoSomething()
}
// 公开函数
func PublicFunc() {
// 导入者可见
}
// 私有函数(导入者不可见)
func privateFunc() {
// 仅包内可用
}
导入者可以访问所有公开内容:
import "mypkg"
func main() {
mypkg.PublicFunc() // 允许访问
// mypkg.privateFunc() // 编译错误:不可见
}
- 局限性:Go 没有类似 Java 的
protected或包级私有修饰符,所有公开内容对导入者完全可见。 - 建议实践:通过最小化公开接口(如仅暴露接口类型)来隐含契约,例如:
// 包内隐藏实现细节
type internalImpl struct{}
func (i internalImpl) DoSomething() {}
// 仅返回接口类型
func New() MyContract {
return internalImpl{}
}

