这是我参与「第三届青训营 -后端场」笔记创作活动的的第1笔记
day1
Why Go
- 大量公司拥抱Go语言
- 高性能、高并发
- 语法简单、学习曲线平滑
- 丰富的标准库
- 完善的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
基础语法
定义变量
var a, b int = 1, math.Sin(114514)
var e float64
f := float32(e)
if
if 1 {
//doSomething
}
for
for {
//while(1)
}
for i := 1; ; i++ {
break
}
for i <= 3 {
//while(i<=3)
}
switch
t := time.Now()
switch a{
case t.Hour()<12:
fmt.Println("loomt") // 不用加break也会自动break
case t.Hour()<23:
fmt.Println("dakta")
default:
fmt.Println("114514")
}
数组,但因为长度固定不常用
var a [5]int
b := [5]int{1,2,3,4,5}
var c [2][3]int
切片,类似vector
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println(s[1:2])
[b c]
map
m := make(map[string]int) // 无序,hash
m["loomt"] = 1
m["dakta"] = 2
r, ok = m["ok"]
fmt.Println(r, ok) //0 false
delete(m,"dakta")
m2 := map[string]int{"one": 1, "two": 2}
range
for i, num := range nums {
fmt.Println("index:",i,"num:",num)
}
函数、指针
func exist(m map[string]int, s string) (v int, ok bool) {
v, ok = m[k]
return v, ok
}
func addptr(n *int) {
*n += 2
}
结构体、类成员函数、错误处理
type user struct {
name string
pw string
}
// 类成员函数
func (u *user) resetPw(pw string) {
return u.pw = pw
}
func findUser(users []user, name string) (v *user, err error) {
for _, u = range users {
if u.name == name {
return &u, nil
}
}
return nil, errors.New("not found")
}
func main() {
a := user{name: "loomt", pw: "123456"}
a.resetPw("1024")
if u,err := findUser([]user{{"loomt","1024"}},"dakta"); err != nil {
fmt.Println(err) // 防止下面的空指针
return
} else {
fmt.Println(u.name)
}
}
strings
s := "loomt"
fmt.Println(strings.Contains(s,"l")) // true
fmt.Println(strings.TrimSuffix(s,"oomt")) // l
fmt.Println(strings.Count(s,"o")) // 2
fmt.Println(strings.HasPrefix(s,"lo")) // true
fmt.Println(strings.HasSuffix(s,"mt")) // true
fmt.Println(strings.Index(s,"l")) // 0
fmt.Println(strings.Join([]string{"hello","world!"},",")) // hello,world!
fmt.Println(strings.Repeat(s,2)) // true
fmt.Println(strings.Replace(s,"l","L",-1)) // Loomt
fmt.Println(strings.ToLower(s))
fmt.Println(strings.ToUpper(s))
fmt.Println(len(s))
字符串格式化
s := user{name: "loomt", pw: "123456"}
fmt.Printf("s=%v\n",s)
fmt.Printf("s=%+v\n",s)
fmt.Printf("s=%#v\n",s)
JSON
type user struct {
Name string // 这样得到的json为 Name : xx
Age int `json:"age"` // 这样得到的json为 age : xx
Hobby []string
}
a := user{Name:"loomt", Age:20,Hobby:[]string {"Golang","cpp"}}
buf, err := json.Marchal(a)
if err != nil {
panic(err)
}
fmt.Println(string(buf))
var t user
err = json.Unmarchal(buf,&t)
时间处理
now := time.Now()
t := time.Parse("2006-01-02 15:04:05","2022-03-27 01:25:36")
t.Minute()
now.Unix() //时间戳
string数字转换
strconv.ParseFloat("1.213",64)
strconv.ParseInt("1213",10,64)//十进制
strconv.ParseInt("1213",0,64)//推测进制
n, _ := stronv.Atoi("123")
n, _ := stronv.Itoa(123)
进程
bash `go run goProject/main.go a b c d`
fmt.Println(os.Args) //输出go的可执行文件路径和a b c d
fmt.Println(os.Setenv("PATH")) //获取环境变量
fmt.Println(os.Setenv("AA","BB")) //设置环境变量
buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
if err != nil {
panic(err)
}
fmt.Println(string(buf)) //127.0.0.1 localhost
项目
-
guess number
简单的用go实现的猜数字游戏
-
翻译api
通过查看源码并使用工具Convert curl commands to code模拟POST请求,将得到的JSON结果转换成Go结构体 (结构体生成工具:okTools
-
socks5代理
网络相关,一步步用Go实现socks5代理,主要是模拟socks协商(握手)、认证、请求
小技巧
- 执行任意一个后退出
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // defer是从下往上执行,防御式编程
go func() {
// 相当于线程1
cancel()
}()
go func() {
// 相当于线程2
cancel()
}()
<-ctx.Done() // 等子线程退出后再返回
- 并行后退出
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
que(word)
}()
go func() {
defer wg.Done()
query(word)
}()
wg.Wait()