1. Go的下载、安装与配置
1.1 Go的下载
根据自己计算机的芯片类型和操作系统,从Go语言官方网站 https://golang.google.cn/dl/
选择相应的稳定版(Stable versions)的安装包进行下载。以Go v1.22.3在macOS(arm64/Apple Silicon)为例,可在终端(Terminal)中执行以下命令行进行下载,并使用sha256sum
命令进行下载文件完整性校验:
mkdir -p /opt/go
cd /opt/go
wget -c "https://golang.google.cn/dl/go1.22.3.darwin-arm64.tar.gz" -O go1.22.3.darwin-arm64.tar.gz
echo "02abeab3f4b8981232237ebd88f0a9bad933bc9621791cd7720a9ca29eacbe9d *go1.22.3.darwin-arm64.tar.gz" | sha256sum -c -
1.2 Go的安装与环境配置
以将Go安装到/opt/go/1.22.3/
下为例进行说明,可在终端(Terminal)中执行以下命令:
tar -zxvf go1.22.3.darwin-arm64.tar.gz
mv go 1.22.3
rm -f go1.22.3.darwin-arm64.tar.gz
配置Go相关的环境变量,可将以下SHELL代码片段添加到.bashrc或.profile中,推荐保存到/etc/profile.d/go.sh
中:
if [ -z "${GOROOT}" ] ; then
go_version="1.22.3"
go_root="/opt/go/${go_version}"
if [ -x "${go_root}/bin/go" ] ; then
GOROOT="${go_root}" ; export GOROOT
GOPATH="/data/repo/go" ; export GOPATH
GOPROXY="https://mirrors.aliyun.com/goproxy/,direct" ; export GOPROXY
# GO111MODULE="on" ; export GO111MODULE
PATH=${GOROOT}/bin:${GOPATH}/bin:${PATH} ; export PATH
fi
unset go_root
unset go_version
fi
其中,GOPROXY
环境变量使用Go模块包阿里云国内镜像地址进行设置以进行加速,Go模块安装到/data/repo/go
下(请先创建该目录)。
1.3 安装Go的gopls、delve及staticcheck
- gopls: 读音:“Go please”,是Go官方开发团队开发的Go语言服务器,为兼容LSP的编辑器如Visual Studio Code提供Go语言IDE相关功能;
- delve:Go语言的调试器;
- staticcheck: Go语言的静态分析器(static analysis),用于分析查找缺陷(Bug)和性能问题给出提示,强化编程规范。
可在终端(Terminal)中执行以下命令进行安装:
go install golang.org/x/tools/gopls@latest
go install github.com/go-delve/delve/cmd/dlv@latest
go install -v honnef.co/go/tools/cmd/staticcheck@latest
2. Visual Studio Code软件及Go相关插件的下载、安装与配置
根据自己计算机的芯片类型和操作系统,从Visual Studio Code官方网站 https://code.visualstudio.com/Download 下载安装Visual Studio Code,安装后在Visual Studio Code插件扩展市场搜索“Go”,找到“Go-Rich Go language support for Visual Studio Code”插件进行安装。可在终端(Terminal)中执行以下命令进行安装Visual Studio Code,供参考:
wget -c "https://code.visualstudio.com/sha/download?build=stable&os=darwin-arm64" -O VSCode-darwin-arm64.zip
echo "1ab1a3776be133c9e9cf7e516d9a6470adb5a89d39e37357f6a7cc81cd0a0a3e *VSCode-darwin-arm64.zip" | sha256sum -c -
unzip VSCode-darwin-arm64.zip
mv Visual\ Studio\ Code.app/ /Applications/
3. Go语言的开发步骤简介
以下在/data/project/go
下创建demo
项目,简要说明一个Go语言项目开发步骤,可在终端(Terminal)中执行以下命令:
mkdir -p /data/project/go/demo/greetings
mkdir -p /data/project/go/demo/hello
cd /data/project/go/demo/greetings
go mod init aihua.gitlab.com/greetings
cd /data/project/go/demo/hello
go mod init aihua.github.com/hello
go mod edit -replace "aihua.gitlab.com/greetings=../greetings"
go mod tidy
项目初始化后,可在Visual Studio Code中打开/data/project/go/demo
文件夹,新建Go文件编写相关代码及测试代码,单元测试代码以“_test.go”作文件名后缀。
Go代码编写完成后,可使用Visual Studio Code的Run和Debug进行运行和调试。也可可在终端(Terminal)中执行以下命令进行运行与测试:
go test
go test -v
go test -cover
go test -benchmem
go run .
demo项目的说明:
项目的目录结构如下:
.
├── greetings
│ ├── go.mod
│ ├── greetings.go
│ └── greetings_test.go
└── hello
├── go.mod
└── hello.go
在aihua.gitlab.com/greetings
模块未发布时,需要使用go mod edit -replace "aihua.gitlab.com/greetings=../greetings"
及go mod tidy
命令来处理模块的依赖关系。以下是主要的代码,其中demo/hello/hello.go
为主调方法入口。
demo/hello/hello.go代码:
package main
import (
"fmt"
"log"
"aihua.gitlab.com/greetings"
)
func main() {
// Set properties of the predefined Logger, including
// the log entry prefix and a flag to disable printing
// the time, source file, and line number.
log.SetPrefix("greetings: ")
log.SetFlags(0)
// A slice of names.
names := []string{"Gladys", "Samantha", "Darrin"}
// Request greeting messages for the names.
messages, err := greetings.Hellos(names)
if err != nil {
log.Fatal(err)
}
// If no error was returned, print the returned map of
// messages to the console.
fmt.Println(messages)
}
demo/greetings/greetings.go代码:
package greetings
import (
"errors"
"fmt"
"math/rand"
)
// Hello returns a greeting for the named person.
func Hello(name string) (string, error) {
// If no name was given, return an error with a message.
if name == "" {
return name, errors.New("empty name")
}
// Create a message using a random format.
message := fmt.Sprintf(randomFormat(), name)
return message, nil
}
// Hellos returns a map that associates each of the named people
// with a greeting message.
func Hellos(names []string) (map[string]string, error) {
// A map to associate names with messages.
messages := make(map[string]string)
// Loop through the received slice of names, calling
// the Hello function to get a message for each name.
for _, name := range names {
message, err := Hello(name)
if err != nil {
return nil, err
}
// In the map, associate the retrieved message with
// the name.
messages[name] = message
}
return messages, nil
}
// randomFormat returns one of a set of greeting messages. The returned
// message is selected at random.
func randomFormat() string {
// A slice of message formats.
formats := []string{
"Hi, %v. Welcome!",
"Great to see you, %v!",
"Hail, %v! Well met!",
}
// Return one of the message formats selected at random.
return formats[rand.Intn(len(formats))]
}
demo/greetings/greetings_test.go代码:
package greetings
import (
"testing"
"regexp"
)
// TestHelloName calls greetings.Hello with a name, checking
// for a valid return value.
func TestHelloName(t *testing.T) {
name := "Gladys"
want := regexp.MustCompile(`\b`+name+`\b`)
msg, err := Hello("Gladys")
if !want.MatchString(msg) || err != nil {
t.Fatalf(`Hello("Gladys") = %q, %v, want match for %#q, nil`, msg, err, want)
}
}
// TestHelloEmpty calls greetings.Hello with an empty string,
// checking for an error.
func TestHelloEmpty(t *testing.T) {
msg, err := Hello("")
if msg != "" || err == nil {
t.Fatalf(`Hello("") = %q, %v, want "", error`, msg, err)
}
}