Go

来自 Arch Linux 中文维基

Go 是一门受 Google 支持的开源编程语言。根据 Go 文档

Go 表达力强、简洁、干净、高效。它的并发机制使编写能够最大限度地利用多核和联网计算机的程序变得简单,而它新颖的类型系统则使得灵活和模块化程序构造变得可能。Go 可以快速编译成机器代码,同时还具有垃圾回收的便利性和运行时反射的强大功能。它是快速、静态类型的编译语言,同时感觉就像是动态类型的解释型语言。

安装[编辑 | 编辑源代码]

安装 go 软件包,这包含标准 Go 编译器和其他开发工具。可在 go 命令文档(英文)中查看包含的子命令。

其他编译器[编辑 | 编辑源代码]

go 软件包包含标准 Go 编译器(名为 gc)。还可使用下面这些编译器替代。

gccgo[编辑 | 编辑源代码]

gcc-go 软件包提供了 GCC 的一个前端 gccgo。在某些情况下,gccgo 生成的二进制文件可能比 gc 更快,而且可以为更多操作系统和架构生成二进制文件。实践中,对于几乎所有的负载,gc 生成的二进制文件都比 gccgo 更快。

TinyGo[编辑 | 编辑源代码]

TinyGo 是一个基于 LLVM 的编译器,旨在为嵌入式系统和 WebAssembly 生成非常小的二进制文件。其由 tinygo 软件包提供。

工具[编辑 | 编辑源代码]

这些软件包提供 Go 开发者工具:

  • Go tools — 主要用于 Go 程序静态分析的各种工具和 Go 软件包。
https://cs.opensource.google/go/x/tools || go-tools
  • gopls — 官方 Go 语言服务器。
https://pkg.go.dev/golang.org/x/tools/gopls || gopls
  • Delve — Go 编程语言的调试器。
https://github.com/go-delve/delve || delve
  • go-bindata — 一款可从任意文件生成 Go 代码的小工具。可用于在 Go 程序中嵌入二进制数据。
https://github.com/shuLhan/go-bindata || go-bindataAUR, go-bindata-hashicorp
  • GoReleaser — Go 项目的发布自动化工具。
https://goreleaser.com/ || goreleaser
  • gox — Go 交叉编译工具,可并行为多个平台编译。
https://github.com/mitchellh/gox || gox
  • ko — Go 应用程序容器镜像生成器。
https://github.com/ko-build/ko || ko
  • revive — 一个快速、可配置、可扩展、灵活、美观的 Go linter。
https://revive.run/ || revive
  • Staticcheck — 先进的 Go 编程语言 linter。
https://staticcheck.io/ || staticcheck
  • Yaegi — Go 解释器。包括 yaegi 命令行解释器/REPL。
https://github.com/traefik/yaegi || yaegi

安装目录[编辑 | 编辑源代码]

go install 命令会将 Go 可执行文件安装到 GOBIN 环境变量定义的目录或 GOPATH 环境变量第一个条目的 bin 子目录。默认情况下是 ~/go/bin

提示:运行 go env 来查看所有 Go 变量。

为方便起见,可将 bin 子目录添加到 PATH 中:

$ export PATH="$PATH:$(go env GOBIN):$(go env GOPATH)/bin"

更多信息,请参见 如何编写 Go 代码(英文)go help gopath

提示和技巧[编辑 | 编辑源代码]

编译源代码[编辑 | 编辑源代码]

可以编写一个 Hello World 程序,如下所示:

hello.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, Arch!")
}

接着通过 go 工具运行它:

$ go run hello.go
Hello, Arch!

使用标准编译器编译(等价于 go build -compiler=gc hello.go):

$ go build hello.go

使用 gccgo 编译(等价于 go build -compiler=gccgo hello.go):

$ gccgo hello.go -o hello

使用 tinygo 编译:

$ tinygo build -o hello ./hello.go

交叉编译到其他平台[编辑 | 编辑源代码]

标准编译器可以很容易地交叉编译到很多平台。过程根据源代码是否通过 cgo 调用 C 代码而不同。

不使用 cgo[编辑 | 编辑源代码]

如果构建不需要 cgo,则只需将目标操作系统和架构指定为 go build环境变量

$ GOOS=linux GOARCH=arm64 go build .

有关 GOOSGOARCH 的有效组合,请参阅官方文档(英文)

使用 cgo[编辑 | 编辑源代码]

如果构建需要 cgo,则必须通过 CCCXX 环境变量提供 C/C++ 交叉编译器的路径。

假设要为 GOOS=linuxGOARCH=arm64 交叉编译。

首先要安装 aarch64-linux-gnu-gcc 交叉编译器。

这是一个需要 cgo 的简单示例程序,以便测试交叉编译过程:

hello.go
package main

// #include <stdio.h>
// void hello() { puts("Hello, Arch!"); }
import "C"

func main() {
    C.hello()
}

然后,可以这样交叉编译:

$ GOOS=linux GOARCH=arm64 CGO_ENABLED=1 CC=/usr/bin/aarch64-linux-gnu-gcc go build hello.go

可以检查生成的二进制文件的架构确实是 aarch64:

$ file hello
hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=b1d92ae8840a019f36cc2aee4606b6ae4a581bf1, for GNU/Linux 3.7.0, not stripped

如果将 hello 复制到合适的主机,则可以运行:

[alarm@rpi3 ~]$ uname -a
Linux alarm 5.3.8-1-ARCH #1 SMP Tue Oct 29 19:31:23 MDT 2019 aarch64 GNU/Linux
[alarm@arpi3 ~]$ ./hello
Hello, Arch!

故障排除[编辑 | 编辑源代码]

JetBrains Go 插件[编辑 | 编辑源代码]

如果使用 JetBrains IDE,而 Go 插件找不到 Go SDK 路径,则可能是使用了不兼容的软件包。移除 gcc-go 软件包并替换为 go。如果已设置 GOPATH,那 IDE 现在应该可以找到位于 /usr/lib/go 的 Go SDK。

参见[编辑 | 编辑源代码]