go 基础 | 青训营笔记

82 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1笔记

day1

Why Go

  1. 大量公司拥抱Go语言
  2. 高性能、高并发
  3. 语法简单、学习曲线平滑
  4. 丰富的标准库
  5. 完善的工具链
  6. 静态链接
  7. 快速编译
  8. 跨平台
  9. 垃圾回收

基础语法

定义变量

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协商(握手)、认证、请求

小技巧

  1. 执行任意一个后退出
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // defer是从下往上执行,防御式编程
go func() {
	// 相当于线程1
  cancel()
}()
go func() {
	// 相当于线程2
  cancel()
}()
<-ctx.Done() // 等子线程退出后再返回
  1. 并行后退出
var wg sync.WaitGroup
wg.Add(2)
go func() {
	defer wg.Done()
	que(word)
}()
go func() {
	defer wg.Done()
	query(word)
}()
wg.Wait()