Contents

Go basic

1、变量定义

var name string
var isOk bool

// 隐式申明
a := 100
str := "sugar"

// 批量声明
var (
    a string
    b int
    c bool
    d float32
)

// 变量的初始化
var name string = "github"
var age int = 10

var name, age = "github", 11

// 类型推导
var name = "github"
var age = 11

// 常量声明
const pi = 3.1415
const e = 2.7182

const (
    pi = 3.1415
    e = 2.7182
)

// const同时声明多个常量时,如果省略了值则表示和上面一行的值相同。
const (
    n1 = 100
    n2
    n3
)

// 枚举
const (
		n1 = iota //0
		n2        //1
		n3        //2
		n4        //3
	)

// 使用_跳过某些值
const (
		n1 = iota //0
		n2        //1
		_
		n4        //3
	)

2、流程控制

func ifDemo1() {
	score := 65
	if score >= 90 {
		fmt.Println("A")
	} else if score > 75 {
		fmt.Println("B")
	} else {
		fmt.Println("C")
	}
}

func forDemo() {
	for i := 0; i < 10; i++ {
		fmt.Println(i)
	}
}

func forDemo3() {
	i := 0
	for i < 10 {
		fmt.Println(i)
		i++
	}
}

//  无限循环
for {
    循环体语句
}


// switch 语法
func testSwitch3() {
    n := 7
	switch n {
	case 1, 3, 5, 7, 9:
		fmt.Println("奇数")
	case 2, 4, 6, 8:
		fmt.Println("偶数")
	default:
		fmt.Println(n)
	}
}

3、slice

a := []int{1, 2, 3, 4, 5}

// 从切片中删除元素
func main() {
	// 从切片中删除元素
	a := []int{30, 31, 32, 33, 34, 35, 36, 37}
	// 要删除索引为2的元素
	a = append(a[:2], a[3:]...)
	fmt.Println(a) //[30 31 33 34 35 36 37]
}

4、函数

// 匿名函数
	func(x, y int) {
		fmt.Println(x + y)
	}(10, 20)

结构体

// 嵌套匿名字段
type Address struct {
	Province string
	City     string
}

//User 用户结构体
type User struct {
	Name    string
	Gender  string
	Address //匿名字段
}

5、编译

Mac 下编译 Linux 和 Windows平台 64位 可执行程序:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build

# go 1.16+版本
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build

Linux 下编译 Mac 和 Windows 平台64位可执行程序:

CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build

Windows下编译Mac平台64位可执行程序:

SET CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build

国内镜像设置

export GOPROXY=https://goproxy.cn,direct
export GOPATH=/root/go
export GO111MODULE="on"
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOROOT/bin:$GOBIN

6、私有仓库设置

go env -w GOPRIVATE="github.com/private_org/private_repo"

go env -w GOPRIVATE="github.com/private_org"

强制走ssh协议get私有包代码

[url "ssh://git@github.com/"]
	insteadOf = https://github.com/

# 或者
git config --global url."ssh://git@github.com/".insteadOf https://github.com/

# go get/install 默认是走https的,默认go get发起请求使用的是HTTPS,如果自己的私有服务是HTTP的,则需要配置下。

go env -w GOINSECURE=git.local.com

7、makefile

PROJECT_NAME= cli


GOBASE=$(shell pwd)
GOFILES=$(wildcard *.go)


BRANCH := $(shell git symbolic-ref HEAD 2>/dev/null | cut -d"/" -f 3)
# BRANCH := `git fetch --tags && git tag | sort -V | tail -1`
# BUILD := $(shell git rev-parse --short HEAD)
BUILD_DIR := $(GOBASE)/dist
VERSION = $(BRANCH)

BuildTime := $(shell date -u  '+%Y-%m-%d %H:%M:%S %Z')
GitHash := $(shell git rev-parse HEAD)
GoVersion = $(shell go version | cut -d " " -f 3 )
Maintainer := cccc@gmail.com 
KEY := wzFdVccccccccccccccc

PKGFLAGS := " -s -w -X 'main.APPVersion=$(VERSION)' -X 'main.GoVersion=$(GoVersion)'  -X 'main.BuildTime=$(BuildTime)' -X 'main.GitCommit=$(GitHash)' -X 'main.AesKey=$(KEY)'  "

APP_NAME = $(PROJECT_NAME)
# go-pkg.v0.1.1-linux-amd64

.PHONY: clean
clean:
	@-rm -rf dist/$(PROJECT_NAME)* 

.PHONY: serve
serve:
	go run .

.PHONY: build
build: clean
	@go build -trimpath -ldflags $(PKGFLAGS) -o "dist/$(APP_NAME)" 
	@echo "\n******************************"
	@echo "         build succeed "
	@echo "******************************\n"
	@ls -la dist/$(PROJECT_NAME)*
	@echo

.PHONY: build-linux
build-linux: clean
	@go mod tidy
	@GOOS="linux"   GOARCH="amd64" go build -trimpath -ldflags $(PKGFLAGS) -v -o "dist/$(APP_NAME)-linux-amd64"       
	@GOOS="linux"   GOARCH="arm64" go build -trimpath -ldflags $(PKGFLAGS) -v -o "dist/$(APP_NAME)-linux-arm64"    
	@echo "\n******************************"
	@echo "      build linux succeed "
	@echo "******************************\n"
	@ls -la dist/$(PROJECT_NAME)*
	@echo

.PHONY: release
release: clean
	@go mod tidy
	@GOOS="windows" GOARCH="amd64" go build -trimpath -ldflags $(PKGFLAGS) -v -o "dist/$(APP_NAME)-windows-amd64.exe" 
	@GOOS="linux"   GOARCH="amd64" go build -trimpath -ldflags $(PKGFLAGS) -v -o "dist/$(APP_NAME)-linux-amd64"       
	@GOOS="linux"   GOARCH="arm64" go build -trimpath -ldflags $(PKGFLAGS) -v -o "dist/$(APP_NAME)-linux-arm64"       
	@GOOS="darwin"  GOARCH="amd64" go build -trimpath -ldflags $(PKGFLAGS) -v -o "dist/$(APP_NAME)-darwin-amd64"      
	@GOOS="darwin"  GOARCH="arm64" go build -trimpath -ldflags $(PKGFLAGS) -v -o "dist/$(APP_NAME)-darwin-arm64"      
	@echo "\n******************************"
	@echo "        release succeed "
	@echo "******************************\n"
	@ls -la dist/$(PROJECT_NAME)*
	@echo

8、go work

参考链接:https://cloud.tencent.com/developer/article/1970405

go 1.18 新增加 workspace的开发模式,

Go work 使用介绍

1)创建一个workspace

[root@tc ~]$ mkdir github
[root@tc ~]$ cd github

2)创建包 p1

[root@tc p1]$ tree .
.
├── go.mod
└── p1.go

0 directories, 2 files

[root@tc p1]$ cat p1.go 
package p1

import "fmt"

func Hello(obj string) {
        fmt.Printf("Hello %s\n", obj)
}

3)回到github目录,生成go.work

[root@tc github]$ go work init ./p1

[root@tc github]$ cat go.work 
go 1.18

use (
        ./p1
) 

4、创建p2,go

[root@tc p2]$ tree .
.
├── go.mod
└── main.go

0 directories, 2 files
[root@tc p2]$ cat main.go 
package main

import (
        "github.com/serialt/p1"
)

func main() {
        p1.Hello("world")
}
[root@tc p2]$ go run main.go 
Hello world

注意:以上操作不能build成二进制文件,因为p2 没有被添加go work里,需要把p2 添加进go work才能使用,可以直接编辑github目录下的go.work,也可使用go work use p2 把p2添加到go work里,然后再执行go build

[root@tc p2]$ go build
[root@tc p2]$ ls
go.mod  main.go p2
[root@tc p2]$ ./p2 
Hello world

注意:因为此时p1 没有提交到远程git仓库,所以在执行go mod tidy 的时候是会去远程仓库下载解决依赖,可以等p1 开发完后 把p1 提交到远程仓库后再对p2 进行go mod tidy。

9、依赖版本控制

go 版本依赖库管理方式主要有三种

方式1:

v1版本go.mod

module github.com/serialt/sugar

v2版本go.md

module github.com/serialt/sugar/v2

使用库时库名仍然是sugar.xxxx

参考地址

https://github.com/serialt/sugar

方式2:

github.com/go-git/go-git/v5

使用库时候库名是git,使用库名时候会自动去掉go-,直接使用git。

参考地址:

https://github.com/serialt/git-mirror/blob/master/service/github.go

方式3:

gopkg.in/yaml.v3

参考地址:

https://github.com/go-yaml/yaml

使用库是时候是yaml.xxxxx,会自动去掉.v3

注意,以上方式一个repo多个版本共存的基础是需要与go.md对应。

10、可选参数

type Option func(*OptionSet)
func New(opts ...Option){
    //下面设置默认值
	options:=OptionSet{	
		A:"default-a",
		B:"default-b",
		C:"default-c",
	}
	for _,fun:=range opts{
        fun(&options)
	}
}
//如果我们需要提供option选项,比方说设置A
func WithA(a string) Option{
    return func(opt *OptionSet){
        opt.A=a
    }
}
// 使用的时候
a=New(WithA("abc"))

11、进程退出

// 进程持续运行
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGTERM, syscall.SIGINT)
	s := <-c
	slog.Info("Aborting...", "signal", s)
	os.Exit(2)

12、升级Go版本

官方推荐方法示例

[sugar@Sugar ~]🐳 go install golang.org/dl/go1.22.6@latest
go: downloading golang.org/dl v0.0.0-20240806160245-f9b8f0a29fb9
[sugar@Sugar ~]🐳 go1.22.6 download
Downloaded   0.0% (   16384 / 67301095 bytes) ...
Downloaded   1.8% ( 1179648 / 67301095 bytes) ...
Downloaded   7.8% ( 5242880 / 67301095 bytes) ...
Downloaded  12.9% ( 8667136 / 67301095 bytes) ...
Downloaded  18.3% (12337136 / 67301095 bytes) ...
Downloaded  23.9% (16056304 / 67301095 bytes) ...
Downloaded  27.7% (18661344 / 67301095 bytes) ...
Downloaded  31.7% (21348352 / 67301095 bytes) ...
Downloaded  36.9% (24821744 / 67301095 bytes) ...
Downloaded  44.3% (29818880 / 67301095 bytes) ...
Downloaded  50.1% (33750880 / 67301095 bytes) ...
Downloaded  55.6% (37437424 / 67301095 bytes) ...
Downloaded  61.2% (41205680 / 67301095 bytes) ...
Downloaded  65.9% (44367568 / 67301095 bytes) ...
Downloaded  71.8% (48348944 / 67301095 bytes) ...
Downloaded  77.4% (52084672 / 67301095 bytes) ...
Downloaded  82.5% (55492320 / 67301095 bytes) ...
Downloaded  88.9% (59834080 / 67301095 bytes) ...
Downloaded  95.1% (63995424 / 67301095 bytes) ...
Downloaded 100.0% (67301095 / 67301095 bytes)
Unpacking /home/sugar/sdk/go1.22.6/go1.22.6.darwin-arm64.tar.gz ...
Success. You may now run 'go1.22.6'
[sugar@Sugar ~]🐳 

官方推荐方法会把安装包下载到 ~/sdk,GOPATH 设置为 ~/sdk/go,做软链接即可方便使用

[sugar@Sugar sdk]🐳 ll
total 0
lrwxr-xr-x@  1 sugar  staff   27 Jul 24 09:43 go -> /home/sugar/sdk/go1.21.1
drwxr-xr-x  20 sugar  staff  640 Jul 22 20:57 go1.21.1
drwxr-xr-x@ 20 sugar  staff  640 Aug 11 13:07 go1.22.6

gvm shell 简单版,放入bash_profile

gvm(){
MY_GO_VERSION=$1
cd "${HOME}"/sdk

[[ -d "${HOME}"/sdk/go${MY_GO_VERSION} ]] 
if [[ $? -ne 0 ]]; then 
    go install golang.org/dl/go${MY_GO_VERSION}@latest &>/dev/null
    go${MY_GO_VERSION} download   &>/dev/null
fi
ln -snf "${HOME}"/sdk/go${MY_GO_VERSION} "${HOME}"/sdk/go
}
[sugar@Sugar sdk]🐳 gvm 1.22.3
[sugar@Sugar sdk]🐳 go version
go version go1.22.3 darwin/arm64
[sugar@Sugar sdk]🐳 gvm 1.22.6
[sugar@Sugar sdk]🐳 go version
go version go1.22.6 darwin/arm64
[sugar@Sugar sdk]🐳