Golang核心概念验证指南

Golang核心概念验证指南 想要验证一些 Go 语言的概念

  1. 构建 Go 代码 获取他人的代码。让你的代码依赖于他人的代码。创建一个构建。这个构建会生成一个可移植的二进制文件——我可以在我的 Mac 上构建,但构建出的文件可以在 Windows/Linux/任何操作系统上运行,无需修改。 与 Java 和 NodeJs 比较。 代码导入的工作方式类似于 NodeJs,而不同于 Java。 可移植二进制文件的创建方式类似于 Java,而不同于 NodeJs。

  2. 二进制文件的使用 由于这种语言会生成二进制文件,因此与 Java 进行比较。 在 Java 中——作为开发者,我可以获取他人的 jar 文件(该 jar 文件必须是专门为此目的构建的)并在我的代码中导入其公开的方法/函数。他人的代码(源代码)对我不可见,因此他们是安全的,而我只能使用其他开发者公开的内容。 在 Go 中,我无法从我的代码中导入二进制文件公开的方法/函数。如果我的代码依赖于以下项目 A B C D E,我必须明确地依赖于每个项目的源代码。如果我想在我的代码中利用它们的功能,它们的每个可执行文件都是无用的。

  3. 包导入与契约 契约——以类类型的形式——对开发者来说一直很重要。其理念是:作为开发者,我定义我可以处理的内容。任何其他开发者导入我的代码时,将只能“看到”和“使用”我选择或允许他们看到或使用的内容。 作为 Go 开发者,我可以定义契约,但我无法限制其他开发者导入我的代码时仅使用我定义的契约。导入的开发者可以导入我的包中公开的任何其他代码。


更多关于Golang核心概念验证指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复
  1. 我不太确定你在这段话中提及 Java 和 JavaScript 的意图,但一个 Go 可执行文件只能在其编译时所针对的架构/操作系统上运行。为 Mac 编译的二进制文件无法在 Windows 上运行,反之亦然。关于如何进行交叉编译,请查阅 GOOSGOARCH 的文档。
  2. 二进制文件仅针对可执行文件创建。库文件会根据需要在编译时处理,并以静态链接的方式集成到你的二进制文件中。Go 的这种工作方式,基本上允许你部署闭源的可执行文件,但库文件必须对目标用户开源。
  3. 你可以使用 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{}
}
回到顶部