GoLang基础 | 青训营笔记

58 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

一、本堂课重点内容:

  • Go语言特点
  • Go基础语法

二、详细知识点介绍:

  1. Go语言特点
  • 高并发、高性能:标准库支持高性能开发
  • 语法简单、学习曲线平缓
  • 丰富的标准库
  • 完善的工具链
  • 静态链接:容器中的镜像很小
  • 快速编译
  • 跨平台:交叉编译
  • 垃圾回收gc
  1. Go基础语法
  • Hello World
package main

import "fmt"

func main() {
   fmt.Println("hello world!")
}
  • 变量
package main

import (
   "fmt"
   "math"
)

func main() {
   var a = "initial"
   var b, c int = 1, 2
   var d = true
   var e float64
   f := float32(e)
   g := a + "foo"
   fmt.Println(a, b, c, d, e, f)
   fmt.Println(g)
   const s string = "const"
   const h = 300000
   const i = 3e20 / h
   fmt.Println(s, h, i, math.Sin(h), math.Sin(i))
}
  • if else
package main

import "fmt"

func main() {
   if 7%2 == 0 {
      fmt.Println("7 is even")
   } else {
      fmt.Println("7 is odd")
   }

   if 8%2 == 0 {
      fmt.Println("8 is even")
   } else {
      fmt.Println("8 is odd")
   }
   // 表示先赋值,在进行比较大小
   if num := 9; num < 0 {
      fmt.Println(num, "is negative")
   } else if num < 10 {
      fmt.Println(num, "has 1 digit")
   } else {
      fmt.Println(num, "has multiple digit")
   }

}
  • for
package main

import "fmt"

func main() {
   i := 1
   for {
      fmt.Println("loop")
      break
   }
   for j := 7; j < 9; j++ {
      fmt.Println(j)
   }

   for n := 0; n < 5; n++ {
      if n%2 == 0 {
         continue
      }
      fmt.Println(n)
   }
   for i <= 3 {
      fmt.Println(i)
      i++
   }

}
  • switch
package main

import (
   "fmt"
   "time"
)

func main() {
   a := 2
   switch a {
   case 1:
      fmt.Println("one")
   case 2:
      fmt.Println("two")
   case 3, 4:
      fmt.Println("three or four")
   default:
      fmt.Println("other")
   }

   t := time.Now()
   switch {
   case t.Hour() < 12:
      fmt.Println("It's before noon")
   default:
      fmt.Println("It's after noon")
   }
}
  • 数组
package main

import "fmt"

func main() {
   var a [5]int
   a[4] = 100
   fmt.Println(a[4], len(a))

   b := [5]int{1, 2, 3, 4, 5}
   fmt.Println(b)

   var twoD [2][3]int
   for i := 0; i < 2; i++ {
      for j := 0; j < 3; j++ {
         twoD[i][j] = i + j
      }
      fmt.Println("2d: ", twoD)
   }
}
  • 切片(不定长数组)
package main

import "fmt"

func main() {

   s := make([]string, 3)
   s[0] = "a"
   s[1] = "b"
   s[2] = "c"
   fmt.Println("get:", s[2])
   fmt.Println("len:", len(s))

   s = append(s, "d")
   s = append(s, "e", "f")
   fmt.Println(s)

   c := make([]string, len(s))
   copy(c, s)
   fmt.Println(c)

   // 截取指定长度
   fmt.Println(s[2:5])
   fmt.Println(s[:5])
   fmt.Println(s[2:])
   
   good := []string{"g", "o", "o", "d"}
   fmt.Println(good)

}
  • map
package main

import "fmt"

func main() {
   m := make(map[string]int)
   m["one"] = 1
   m["two"] = 2
   fmt.Println(m)
   fmt.Println(len(m))
   fmt.Println(m["one"])
   fmt.Println(m["two"])
   // 当键不存在时,返回默认值
   fmt.Println(m["three"])

   r, ok := m["three"]
   // r为值, ok表示键是否存在
   fmt.Println(r, ok)

   delete(m, "one")
   fmt.Println(m)

   m2 := map[string]int{"one": 1, "two": 2}
   var m3 = map[string]int{"one": 1, "two": 2}
   fmt.Println(m2, m3)

}
  • range
package main

import "fmt"

func main() {
   nums := []int{2, 3, 4}
   sum := 0
   for i, num := range nums {
      sum += num
      if num == 2 {
         fmt.Println("index", i, "num", num)
      }
   }
   fmt.Println(sum)

   m := map[string]string{"a": "A", "b": "B"}
   for k, v := range m {
      fmt.Println(k, v)
   }
   for _, v := range m {
      fmt.Println("key", v)
   }
}
  • 函数
package main

import "fmt"

func add(a int, b int) int {
   return a + b
}

func add2(a, b int) int {
   return a + b
}

func exists(m map[string]string, k string) (v string, ok bool) {
   v, ok = m[k]
   return v, ok
}

func main() {
   res := add(1, 2)
   fmt.Println(res)
   v, ok := exists(map[string]string{
      "a": "A"}, "a")
   fmt.Println(v, ok)

}
  • 指针
package main

import "fmt"

func add2(n int) {
	n += 2
}

func add2ptr(n *int) {
	*n += 2
}

func main() {
	n := 5
	add2(n)
	fmt.Println(n)
	add2ptr(&n)
	fmt.Println(n)
}
  • 结构体
package main

import "fmt"

type user struct {
   name     string
   password string
}

func checkPassword(u user, password string) bool {
   return u.password == password
}

func checkPassword2(u *user, password string) bool {
   return u.password == password
}

func main() {
   a := user{
      name:     "wang",
      password: "1024"}
   b := user{
      "wang",
      "1024"}
   c := user{name: "wang"}
   c.password = "1224"
   var d user
   d.name = "wang"
   d.password = "1024"

   fmt.Println(a, b, c, d)
   fmt.Println(checkPassword(a, "haha"))
   fmt.Println(checkPassword2(&a, "haha"))

}
  • 结构体方法
package main

import "fmt"

type user struct {
   name     string
   password string
}

func (u user) checkPassword(password string) bool {
   return u.password == password
}

func (u *user) resetPassword(password string) {
   u.password = password
}

func main() {
   a := user{
      name:     "wang",
      password: "1024"}
   b := user{
      "wang",
      "1024"}
   c := user{name: "wang"}
   c.password = "1224"
   var d user
   d.name = "wang"
   d.password = "1024"

   fmt.Println(a, b, c, d)
   fmt.Println(a.checkPassword("haha"))
   a.resetPassword("haha")
   fmt.Println(a)
}
  • 错误处理
package main

import (
   "errors"
   "fmt"
)

type user struct {
   name     string
   password string
}

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() {
   u, err := findUser([]user{{"wang", "1024"}}, "wang")
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(u.name)
   if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
      fmt.Println(err)
      return
   } else {
      fmt.Println(u.name)
   }

}
  • 字符串操作
package main

import "fmt"

type point struct {
	x, y int
}

func main() {
	s := "hello"
	n := 123
	p := point{1, 2}
	fmt.Println(s, n)
	fmt.Println(p)

	fmt.Printf("s=%v\n", s)
	fmt.Printf("n=%v\n", n)
	fmt.Printf("p=%v\n", p)
	fmt.Printf("p=%+v\n", p)
	fmt.Printf("p=%#v\n", p)

	f := 3.141592653
	fmt.Println(f)
	fmt.Printf("%.2f\n", f)
}
  • JSON处理
package main

import (
	"encoding/json"
	"fmt"
)

type userInfo struct {
	Name string
	// 字段名改成小写
	Age   int `json:"age"`
	Hobby []string
}

func main() {
	a := userInfo{Name: "wang",
		Age: 18,
		Hobby: []string{
			"Golang", "TypeScript"}}
	// 序列化为byte数组
	buf, err := json.Marshal(a)
	if err != nil {
		panic(err)
	}
	fmt.Println(buf)
	// 将byte数组转化为字符串
	fmt.Println(string(buf))

	buf, err = json.MarshalIndent(a, "", "\t")
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf))

	var b userInfo
	err = json.Unmarshal(buf, &b)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v\n", b)
}

三、实践练习例子:

  • 用代码生成器访问API
package main
import (
   "bytes"
   "encoding/json"
   "fmt"
   "io/ioutil"
   "log"
   "net/http"
   "os"
)

type DictRequest struct {
   TransType string `json:"trans_type"`
   Source    string `json:"source"`
   UserID    string `json:"user_id"`
}

type DictResponse struct {
   Rc   int `json:"rc"`
   Wiki struct {
      KnownInLaguages int `json:"known_in_laguages"`
      Description     struct {
         Source string      `json:"source"`
         Target interface{} `json:"target"`
      } `json:"description"`
      ID   string `json:"id"`
      Item struct {
         Source string `json:"source"`
         Target string `json:"target"`
      } `json:"item"`
      ImageURL  string `json:"image_url"`
      IsSubject string `json:"is_subject"`
      Sitelink  string `json:"sitelink"`
   } `json:"wiki"`
   Dictionary struct {
      Prons struct {
         EnUs string `json:"en-us"`
         En   string `json:"en"`
      } `json:"prons"`
      Explanations []string      `json:"explanations"`
      Synonym      []string      `json:"synonym"`
      Antonym      []string      `json:"antonym"`
      WqxExample   [][]string    `json:"wqx_example"`
      Entry        string        `json:"entry"`
      Type         string        `json:"type"`
      Related      []interface{} `json:"related"`
      Source       string        `json:"source"`
   } `json:"dictionary"`
}

func query(word string) {
   client := &http.Client{}
   //var data = strings.NewReader(`{"trans_type":"en2zh","source":"good"}`)
   request := DictRequest{TransType: "en2zh", Source: word}
   buf, err := json.Marshal(request)
   if err != nil {
      log.Fatal(err)
   }
   var data = bytes.NewReader(buf)
   req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
   if err != nil {
      log.Fatal(err)
   }
   req.Header.Set("authority", "api.interpreter.caiyunai.com")
   req.Header.Set("accept", "application/json, text/plain, */*")
   req.Header.Set("accept-language", "zh-CN,zh;q=0.9")
   req.Header.Set("app-name", "xy")
   req.Header.Set("content-type", "application/json;charset=UTF-8")
   req.Header.Set("device-id", "")
   req.Header.Set("origin", "https://fanyi.caiyunapp.com")
   req.Header.Set("os-type", "web")
   req.Header.Set("os-version", "")
   req.Header.Set("referer", "https://fanyi.caiyunapp.com/")
   req.Header.Set("sec-ch-ua", `"Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"`)
   req.Header.Set("sec-ch-ua-mobile", "?0")
   req.Header.Set("sec-ch-ua-platform", `"Windows"`)
   req.Header.Set("sec-fetch-dest", "empty")
   req.Header.Set("sec-fetch-mode", "cors")
   req.Header.Set("sec-fetch-site", "cross-site")
   req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36")
   req.Header.Set("x-authorization", "token:qgemv4jr1y38jyq6vhvi")
   resp, err := client.Do(req)
   if err != nil {
      log.Fatal(err)
   }
   defer resp.Body.Close()
   bodyText, err := ioutil.ReadAll(resp.Body)
   if err != nil {
      log.Fatal(err)
   }
   //fmt.Printf("%s\n", bodyText)
   var dictResponse DictResponse
   err = json.Unmarshal(bodyText, &dictResponse)
   if err != nil {
      log.Fatal(err)
   }
   //cfmt.Printf("%#v\n", dictResponse)
   for _, item := range dictResponse.Dictionary.Explanations {
      fmt.Println(item)
   }
}

func main() {
   if len(os.Args) != 2 {
      fmt.Println(os.Stderr, `usage: simpleDict WORD example: simpleDict hello`)
      os.Exit(1)
   }
   word := os.Args[1]
   query(word)
}
  • socks5实现
package main

import (
	"bufio"
	"log"
	"net"
)

func main() {
	server, err := net.Listen("tcp", "127.0.0.1:1080")
	if err != nil {
		panic(err)
	}

	for {
		client, err := server.Accept()
		if err != nil {
			log.Printf("Accept failed %v", err)
			continue
		}
		go process(client)
	}

}

func process(conn net.Conn) {
	defer conn.Close()
	reader := bufio.NewReader(conn)
	for {
		b, err := reader.ReadByte()
		if err != nil {
			break
		}
		_, err = conn.Write([]byte{b})
		if err != nil {
			break
		}
	}
}