GolangNO.1:基础语法 | 青训营笔记

155 阅读3分钟

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

Go基础

1.Golang概述

1.1 golang特征
①高性能,高并发
②语法简单学习曲线平缓
③丰富的标准库
④完善的工具链
⑤静态链接
⑥快速编译
⑦跨平台
⑧垃圾回收机制

2.Golang语法

2.1 变量

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 = "constant"
   const h = 5000000000
   const i = 3e20 /h
   fmt.Println(s,h,i,math.Sin(h),math.Sin(i))
}

2.2 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 % 4 == 0 {
      fmt.Println("8 is divisible by 4")
   }

   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 digits")
   }
}

2.3 循环

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 = i + 1
   }
}

2.4 switch分支结构

package main

import (
   "fmt"
   "time"
)

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

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

   
}

2.5 数组

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)
}

2.6 切片

package main

import (
   "fmt"
)

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

   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]) //[c d e]
   fmt.Println(s[:5])
   fmt.Println(s[2:])

   good := []string{"g","o","o","d"}
   fmt.Println(good)
}

2.7 map

package main

import (
   "fmt"
)

func main (){
   
   m := make(map[string]int)
   m["one"] = 1
   m["two"] = 2
   fmt.Println(m)
   fmt.Println(m["one"])
   fmt.Println(m["two"])
   fmt.Println(m["unknow"])

   r, ok := m["unknow"]
   fmt.Println(r,ok)//0 false

   delete(m,"one")

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

2.8 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) //9

   m := map[string]string{"a": "A","b":"B"}

   for k,v := range m {
      fmt.Println(k,v)
   }
   for k := range m {
      fmt.Println("key",k)
   }
}

2.9 函数

package main

import (
   "fmt"
)
   
func add(a int,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)
}

2.10 指针

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)
}

2.11 结构体

package main

import (
   "fmt"
)

type user struct {
   name string
   password string
}

func main(){
   a := user{name:"wang",password: "1024"}
   b := user{"wang","1024"}
   c := user{name:"wang"}
   c.password = "1024"
   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"))
}

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

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

2.12 结构体方法

package main

import (
   "fmt"
)

type user struct {
   name string
   password string
}

func main(){
   a := user{"wang","1024"}
   a.resetPassword("2048")
   fmt.Println(a.checkPassword("2048"),a)
}

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

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

2.13 错误的处理

package main

import (
   "errors"
   "fmt"
)

type user struct {
   name string
   password string
}

func main(){
   u, err := findUser([]user{{"wang","1024"}},"wang")

   if err != nil {
      fmt.Println(err)   
      return
   }
   fmt.Println(u.name)   //wang

   if u,err := findUser([]user{{"wang","1024"}},"li");err != nil {
      fmt.Println(err)   //not found
      return
   }else {
      fmt.Println(u.name)
   }
}

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")
}

2.14 字符串操作

package main

import (
	"fmt"
	"strings"
)

type user struct {
   name string
   password string
}

func main(){
   a := "hello"
   fmt.Println(strings.Contains(a,"ll"))  //true
   
   fmt.Println(strings.Count(a,"l"))   //2
  
   fmt.Println(strings.HasPrefix(a,"he"))   //true
   fmt.Println(strings.HasSuffix(a,"llo"))   //true
   
   fmt.Println(strings.Index(a,"ll"))     //2

   fmt.Println(strings.Join([]string{"he","llo"},"-")) //he-llo
   fmt.Println(strings.Repeat(a,2))          //hellohello
   fmt.Println(strings.Replace(a,"e","E",-1))      //hEllo
   fmt.Println(strings.Split("a-b-c","-"))      //[a b c]

   fmt.Println(strings.ToLower(a))
   fmt.Println(strings.ToUpper(a))
   fmt.Println(len(a))        //5
   b := "你好"
   fmt.Println(len(b))     //6
}

2.15 字符串格式化

package main

import (
	"fmt"
)

type point struct {
   x,y int
}

func main(){
   s := "hello"
   n := 123
   p := point{1,2}
   fmt.Println(s,n)        //hello 123
   fmt.Println(p)          //{1,2}
   fmt.Printf("s=%v\n",s)     //s=hello
   fmt .Printf("n=%v\n",n)    //n=123
   fmt.Printf("p=%v\n",p      )//p=(1 2)
   fmt.Printf("p=%+v\n",p)    //p=(x:1 y:2)
   fmt.Printf("p=%#v\n",p)    //p=main.point(x:1,y:2)
   f:=3.141592653
   fmt.Println(f)          //3.141592653
   fmt.Printf("%.2f\n",f)     //3.14
}

2.16 Json处理

package main

import (
	"encoding/json"
	"fmt"
)

type userInfo struct {
   Name string
   Age int
   Hobby []string
}

func main(){
   a := userInfo{"wang",18,[]string{"Golang","TypeScript"}}
   buf,err := json.Marshal(a)
   if err != nil {
      panic(err)
   }
   fmt.Println(string(buf))

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

2.17 时间处理

package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()
	fmt.Println(now)

	t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
	t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
	fmt.Println(t)
	fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute())
	fmt.Println(t.Format("2006-01-02 15:04:05"))
	diff := t2.Sub(t)
	fmt.Println(diff)
	fmt.Println(diff.Minutes(), diff.Seconds())
	t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
	if err != nil {
		panic(err)
	}
	fmt.Println(t3 == t)
	fmt.Println(now.Unix()) //时间戳
}

2.18 数字解析

package main

import (
	"fmt"
	"strconv"
)

func main() {
	f,_ := strconv.ParseFloat("1.234",64)
   fmt.Println(f)
   fmt.Printf("%T\n",f)

   n,_ := strconv.ParseInt("111",10,64)
   fmt.Println(n)
   fmt.Printf("%T\n",n)

   n,_= strconv.ParseInt("0x1000",0,64)
   fmt.Println(n)
   fmt.Printf("%T\n",n)

   n2,_ := strconv.Atoi("123")
   fmt.Println(n2)
   fmt.Printf("%T\n",n2)

   n2,err := strconv.Atoi("AAA")
   fmt.Println(n2,err)
   fmt.Printf("%T\n",n2)
}

2.19 进程信息

package main

import (
	"fmt"
	"os"
       "os/exec"
)

func main() {
   fmt.Println(os.Args)   
   fmt.Println(os.Getenv("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))
}

3.实战

3.1 猜谜游戏

package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"time"
)

func main() {
	maxNum := 100
	//用时间戳来初始化随机数种子,否则会一直生成一个数
	rand.Seed(time.Now().UnixNano())
	secretNumber := rand.Intn(maxNum)
	fmt.Println(secretNumber)

	fmt.Println("Please input your guess")
	reader := bufio.NewReader(os.Stdin)
	for {

		input, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("An error occured while reading input.Please try again", err)
			continue
		}
		input = strings.TrimSuffix(input, "\r\n")

		guess, err := strconv.Atoi(input)
		if err != nil {
			fmt.Println("Invalid input.Please enter on integer value")
			continue
		}
		fmt.Println("Your guess is ", guess)

		if guess > secretNumber {
			fmt.Println("Your guess is bigger than the secret number.Please try again")
		} else if guess < secretNumber {
			fmt.Println("Your guess is smaller than the secret number.Please try again")
		} else {
			fmt.Println("Correct,you Legend!")
			break
		}
	}

}

3.2 在线词典

1.调取彩云小译的API: 进入 (fanyi.caiyunapp.com/#/) 随机翻译一个字符串。在F12中的网络的预览 dict 中,查看到生成的一大串JSON文字。后右键dict选择 赋值 curl,进入 (curlconverter.com/#go) 下转换GOLANG代码。后复制粘贴。

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)



func main() {
	client := &http.Client{}
	var data = strings.NewReader(`{"trans_type":"en2zh","source":"good"}`)
	//创建请求
	req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
	if err != nil {
		log.Fatal(err)
	}
	//设置请求头
	req.Header.Set("Accept", "application/json, text/plain, */*")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
	req.Header.Set("Connection", "keep-alive")
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	req.Header.Set("Origin", "https://fanyi.caiyunapp.com")
	req.Header.Set("Referer", "https://fanyi.caiyunapp.com/")
	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/101.0.4951.41 Safari/537.36 Edg/101.0.1210.32")
	req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi")
	req.Header.Set("app-name", "xy")
	req.Header.Set("os-type", "web")
	req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="101", "Microsoft Edge";v="101"`)
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("sec-ch-ua-platform", `"Windows"`)
	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)
}

复制刚刚 dict页面下的 预览内容 至 (oktools.net/json2go) 转换为结构体,并改名为 DictResponse 。再补全下列代码,即可完成与页面上一样的效果。

完整代码

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
)

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"`
}

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

func query(word string) {
	client := &http.Client{}
	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("Accept", "application/json, text/plain, */*")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
	req.Header.Set("Connection", "keep-alive")
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	req.Header.Set("Origin", "https://fanyi.caiyunapp.com")
	req.Header.Set("Referer", "https://fanyi.caiyunapp.com/")
	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/101.0.4951.41 Safari/537.36 Edg/101.0.1210.32")
	req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi")
	req.Header.Set("app-name", "xy")
	req.Header.Set("os-type", "web")
	req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="101", "Microsoft Edge";v="101"`)
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("sec-ch-ua-platform", `"Windows"`)
	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)
	}
	//fmt.Println("%#v\n",dictResponse)
	//fmt.Println(word,"UK:",dictResponse.Dictionary.Prons.En,"US:",dictResponse.Dictionary.Prons.EnUs)

	for _, item := range dictResponse.Dictionary.Explanations {
		fmt.Println(item)
	}

}

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

3.3 网络编程

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
		}
	}
}