Go_base

Posted by Zhenda on Wed, Sep 25, 2024
Total Views:

[toc]

资料

一个Go项目中只能有一个 main 包和一个 main() 函数 在Go语言中,所有可执行代码必须在函数内部(通常是main函数)。

你会直接编辑 go.mod(虽然通常通过 Go 命令来做),但永远不应该手动编辑 go.sum 用于管理项目的依赖关系。它们共同保证了项目的构建过程的可靠性和可重复性

go 版本切换

  • gvm
  • asdf

go env

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
zhenda@yoga-13s-2021:~$ go env
GOPATH='/home/zhenda/go'
GOROOT='/usr/local/go'
GOPROXY='https://proxy.golang.org,direct'
GOTOOLCHAIN='auto'

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/zhenda/.cache/go-build'
GOENV='/home/zhenda/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/zhenda/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPRIVATE=''
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.23.1'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/zhenda/.config/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2891050929=/tmp/go-build -gno-record-gcc-switches'
1
2
echo 'export PATH=$PATH:$HOME/go/bin' >> ~/.bashrc
source ~/.bashrc

网络配置, 国内被墙

1
setx GOPROXY "https://goproxy.cn,direct"
1
2
go env -w GOPROXY=https://goproxy.cn,direct
go env -w GOSUMDB=off

交互式环境(REPL)

1
2
3
4
5
go install github.com/x-motemen/gore/cmd/gore@latest

go: github.com/x-motemen/gore@v0.6.1 requires go >= 1.24; switching to go1.24.11
go: downloading go1.24.11 (linux/amd64)
go: download go1.24.11: golang.org/toolchain@v0.0.1-go1.24.11.linux-amd64: verifying module: checksum database disabled by GOSUMDB=off
1
2
3
4
5
6
7
8
9
gore> :help
    :import <package>     import a package
    :type <expr>          print the type of expression
    :print                print current source
    :write [<file>]       write out current source
    :clear                clear the codes
    :doc <expr or pkg>    show documentation
    :help                 show this help
    :quit                 quit the session

go版本升级, 多版本

windows环境

1
2
3
4
5
6
7
8
# 安装Scoop后
scoop install go

# 安装多版本
scoop install go@1.20

# 切换版本
scoop reset go@1.20

Linux环境

手动安装多版本

1
2
3
4
5
6
# 下载不同版本
wget https://go.dev/dl/go1.21.0.linux-amd64.tar.gz
wget https://go.dev/dl/go1.20.0.linux-amd64.tar.gz
# 解压到不同目录
sudo mv /usr/local/go /usr/local/go1.21.0
sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz

切换版本:修改PATH环境变量

  1. 使用命令直接切换
1
export PATH="/usr/local/go1.21.0/bin:$PATH"
  1. 使用脚本切换版本

创建简单的切换脚本 switch-go.sh:

1
2
3
4
#!/bin/bash
export GOROOT="/usr/local/go$1"
export PATH="$GOROOT/bin:$PATH"
go version

使用:

1
source switch-go.sh 1.21.0

常用命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 初始化项目
go mod init mypj
# 更新依赖
go get -u
go get -u xxx
go get .
# 更新go.mod文件
go mod tidy
# 查看依赖
go list -m all

go run .
# 打包main包
go build
go test xxx
# 使用 air 进行热重载
air

基本调试

1
2
3
4
5
6
7
8

func main() {
    const name, age = "Kim", 22
    fmt.Println(name, "is", age, "years old.")

    // 查看数据的类型
    fmt.Printf("%T, %T\n", ptrs, ptrs2)
}

数据结构

变量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
/*
这是一个多行注释
可以用于注释多行内容
*/

// 单行注释

/* 
- rune 用于表示 字符(尤其是 Unicode 字符),是 32 位 的带符号整数。
- byte 是 uint8 的别名,表示无符号的 8 位整数,范围从 0 到 255。用于表示 字节,它是 8 位 无符号整数,通常用于处理 ASCII 字符和原始二进制数据。
*/

var i byte
var i int
var f float64 = 3.14
// 短赋值语句 := 可在隐式确定类型的 var 声明中使用, 不能在函数外使用
name := "Alice" // 简短变量声明

make([]T, length, capacity) 用于创建切片、映射和通道

1
a := make([]int, 3)

数组, 固定长度, 几乎不怎么用

1
2
var arr [5]int = [5]int{1, 2, 3, 4, 5}
arr[2] = 10

slice, 可以动态改变大小,每个子切片的长度可以不同,适合处理大小不定或动态的数据

1
2
3
4
var s []int = []int{1, 2, 3, 4}
s = append(s, 5)

a := [][]int{{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}

map

1
2
3
m := make(map[string]int)
m["age"] = 30
delete(m, "age")

pointer

1
2
3
var x int = 10
var p *int = &x
fmt.Println(*p) // 输出 10

结构体

1
2
3
4
type Person struct {
    Name string
    Age  int
}

channel(通道)是 Go 中用于在 goroutine 之间传递值的类型,常用于同步和通信

1
2
3
4
5
6
7
8
9
ch := make(chan int)
go func() {
    ch <- 1
    ch <- 2
    close(ch)
}()
for v := range ch {
    fmt.Println(v)
}

类型转换

1
2
var a int = 10
var b float64 = float64(a)

函数

控制逻辑

for

1
2
3
4
5
6
7
8
// 相当于 python 的 enumerate
for index, value := range arr {
    fmt.Println(index, value)
}

for i := 0; i < 5; i++ {
    fmt.Println(i)
}

if

1
2
3
4
5
if x > 10 {
    fmt.Println("x is greater than 10")
} else {
    fmt.Println("x is less than or equal to 10")
}

函数

1
2
3
func greet(name string) {
    fmt.Printf("Hello, %s!\n", name)
}

interface

1
2
3
4
type Animal interface {
    move()
    eat()
}

package xxx

xxx 就是包名, 基本等于文件夹名

文件夹内的函数不能重名

常用工具包

包名功能常用函数
fmt格式化输入输出Println, Printf, Sprintf
strings字符串处理Split, Contains, Replace, ToLower
strconv字符串转换Atoi, ParseInt, Itoa, FormatInt
math数学函数Max, Min, Sqrt, Pow, Abs
os操作系统接口Open, Create, ReadFile, WriteFile
io输入输出接口Reader, Writer, Copy
log日志记录Println, Fatal, Panic
time时间处理Now, Sleep, Parse, Format
sort排序Ints, Strings, Sort, Reverse
errors错误处理New, Is, As
bufio缓冲 I/OScanner, Reader, Writer
jsonJSON 处理Marshal, Unmarshal
encoding/jsonJSON 编码和解码Marshal, Unmarshal
encoding/xmlXML 编码和解码Marshal, Unmarshal
encoding/csvCSV 编码和解码NewReader, NewWriter
container/list链表New, PushBack, Remove
container/heapPush, Pop, Init
net/httpHTTP 客户端和服务器Get, Post, ListenAndServe
net/urlURL 解析和构建Parse, URL, QueryEscape
context上下文管理Background, WithCancel, WithTimeout
database/sql数据库操作Open, Query, Exec
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import (
    "fmt"
    "strings"
    "strconv"
    "math"
    "os"
    "io"
    "log"
    "time"
    "sort"
    "errors"
    "bufio"
    "encoding/json"
    "net/http"
    "context"
    "database/sql"
)

func main() {
    // 示例代码
    fmt.Println("Hello, Go!")
}

并发

并发模型基于 goroutine 和 channel

goroutine 超轻量(几 KB) channel 天然适合事件驱动系统

部署

部署极其容易, 生成一个二进制文件, 直接运行

内存管理

Go 的 GC 模型 来并发回收