Try my best to be best
相关文章: vscode搭建go语言开发环境
将go文件编译成可执行文件 go build hello.go
去除调试信息和符号表以节约可执行文件大小 go build -ldflags "-w -s"
交叉编译(如使用windows编译成linux的可执行文件)
SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build -ldflags "-s -w" -o hello hello.go
相关文章: godoc 命令和 golang 代码文档管理
# 查看目标包的文档索引
go doc [targetPackage]
# 查看目标包的某内容的文档索引
go doc [targetPackage].[函数名]
# 或者空格隔开也显示某内容的文档
go doc [targetPackage] [函数名]
# 子包的文档注释
go doc [targetPackage]/[subpackage]
# 代码文档编写, 按 go 的标准注释写法编写
// Biz implements a business
type Biz struct {
}
// business initialization
func (b *Biz) Init() {
}
相关文章: go mod 使用
# 配置 go mod
export GO111MODULE=true
# 创建新项目
go mod init hello
# 接下来几乎可以不用管了,在使用第三方包时import, 在运行时会自动从网上下载依赖
# go module 安装 package 的原則是先拉最新的 release tag,若无tag则拉最新的commit
# 使用go get时也会由go mod接管
# 运行 go get -u 将会升级到最新的次要版本或者修订版本(x.y.z, z是修订版本号, y是次要版本号)
# 运行 go get -u=patch 将会升级到最新的修订版本
# 运行 go get [email protected] 将会升级到指定的版本号version
# 运行go get如果有版本的更改,那么go.mod文件也会更改
# 使用go mod时引入当前文件夹下的包不能再使用 ./package, 而是使用 project/package
# 常用的go mod命令
go mod tidy # 自动安装所缺的依赖包以及去除无用的依赖包
相关文章 Go五种定义变量的方法
在函数之外不能使用a := value
的语句定义变量
通常使用以下语句定义全局变量
var (
WG sync.WaitGroup
LOCK sync.Mutex
)
通常使用以下语句定义常量
const (
PI float64 = 3.14
WEIGHT int = 5
)
相关文章 Go Struct 超详细讲解
特别注意的是go结构体中的匿名字段,看以下两种写法
// 写法一
package main
import (
"fmt"
)
type Animal struct {
Name string
Color string
}
func (a *Animal) Run() {
fmt.Println(a.Name, a.Color)
}
type Lion Animal // Lion是Animal的别名,这样只能继承Animal的属性,而无法调用Animal的方法,解决方法是使用接口/实现func (a *Lion) Run()
func main() {
var lion = Lion{
Name: "小狮子",
Color: "灰色",
}
// 无法调用lion.Run()
fmt.Println(lion.Name)
}
// 写法二
package main
import (
"fmt"
)
type Animal struct {
Name string
Color string
}
func (a *Animal) Run() {
fmt.Println(a.Name, a.Color)
}
type Lion struct {
Animal //匿名字段,这样组合了Animal的特性,可以直接使用func (a *Animal) Run()
}
func main() {
var lion = Lion{
Animal{
Name: "小狮子",
Color: "灰色",
},
}
lion.Run()
fmt.Println(lion.Name)
}
go中定义接口使用type和interface关键字
在Go中,定义一个interface类型,该类型说明了它有哪些方法,然后在其他的函数中,将该interface类型作为函数的形参,任意一个实现了interface类型的实参都能作为该interface的实例对象
示例如下
package main
import "fmt"
type Animal interface {
Say()
}
type Dog struct {
age int
}
func (a *Dog) Say() {
fmt.Println("Dog say: I am ", a.age)
}
type Cat struct {
age int
}
func (a *Cat) Say() {
fmt.Println("Cat say: I am ", a.age)
}
func AnimalSay(a Animal) {
a.Say()
}
func main() {
dog := Dog{age: 2}
cat := Cat{age: 3}
AnimalSay(&dog)
AnimalSay(&cat)
}
相关文章: Golang异常处理机制 Golang错误和异常处理的正确姿势
go中使用defer, error, panic, recover处理异常
defer
import (
"net"
"fmt"
)
func func() {
conn, err := net.Dial("tcp","127.0.0.1:8080")
defer conn.close()
if err != nil {
fmt.Println("Connect Error:", err)
} else {
fmt.Println("Connect OK.")
}
}
error
error的接口如下
type error interface {
Error() string
}
package main
import (
"fmt"
"strconv"
)
type TestError struct {
ErrorCode int
}
func (err *TestError) Error() string {
return "TestError: error code " + strconv.Itoa(err.ErrorCode)
}
func Test() error {
return &TestError{
ErrorCode: 1,
}
}
func main() {
err := Test()
if err != nil {
fmt.Println(err)
fmt.Println("Golang custom error is easy!")
}
}
panic和recover
package main
import (
"fmt"
)
func Test() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Panic info is:", r)
}
}()
panic("Oh no panic!")
}
func main() {
Test()
}
并发
golang中使用go关键字开启一个新的协程(goroutine)
协程默认是单核并发的,可以通过runtime.GOMAXPROCS(cpuNum)
来使其多核并行
子协程会在主协程退出时退出
示例如下
package main
import (
"os"
"time"
)
func test() {
for {
file, _ := os.OpenFile("test2.txt", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0664)
file.WriteString("hello world\n")
file.Sync()
file.Close()
time.Sleep(1 * time.Second)
}
}
func main() {
go test()
time.Sleep(3 * time.Second)
}
信道
相关文章 详解Go信道
golang中使用chan来声明一个信道
信道有容量和长度之分,有缓存与无缓存之分,有双向与单向之分
可以使用信道做锁, 示例如下
package main
import (
"fmt"
"os"
"time"
)
func test(ch chan<- bool) {
file, _ := os.OpenFile("test2.txt", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0664)
file.WriteString("hello world\n")
file.Sync()
file.Close()
time.Sleep(1 * time.Second)
ch <- true
}
func main() {
ch := make(chan bool)
go test(ch)
<-ch
fmt.Println("finish")
}
go中存在标准库sync
锁的使用, 示例如下
// 定义一个锁
var lock sync.Mutex
// 使用锁
func test() {
lock.Lock()
defer lock.Unlock()
// do something
}
// 注意不要在锁已Lock的时候再次请求锁,会造成死锁并且不会引发panic
WaitGroup的使用, 示例如下
// 定义一个WaitGroup
var wg sync.WaitGroup
// 使用WaitGroup优雅地等待子协程结束
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func test(i int) {
wg.Add(1)
defer wg.Done()
fmt.Println("here is ", i, "goroutine")
}
func main() {
for i := 0; i < 10; i++ {
go test(i)
}
wg.Wait()
fmt.Println("Done")
}