go后端学习-第一节

​ 学习完第一节课后,根据课程内容进行一个简单的总结。

基本格式

​ 下面是一个最基本的hello world程序。其中package main表示该文件属于哪一个包,紧接着是import表示需要导入的包文件,fmt主要是输出到屏幕上;然后就是main函数。

package main

import "fmt"

func main() {
    fmt.Println("hello, world!")
}

​ Go语言主要有四种类型的声明语句:var、const、type和func,分别对应变量、常量、类型和函数实体对象的声明。

package main

import "fmt"

const boilingF = 212.0

func main() {
    var f = boilingF
    var c = (f - 32) * 5 / 9
    fmt.Printf("boiling point = %g°F or %g°C\n", f, c)
}
  • 常量:采用const进行声明,其中boilingF就是一个常量
  • 变量:采用var进行声明,其中f和c都是变量
  • 函数:一个函数的声明由一个函数名字、参数列表(由函数的调用者提供参数变量的具体值)、一个可选的返回值列表和包含函数定义的函数体组成。如果函数没有返回值,那么返回值列表是省略的。执行函数从函数的第一个语句开始,依次顺序执行直到遇到return返回语句,如果没有返回语句则是执行到函数末尾,然后返回到函数调用者
  • Type:用于结构体的申明

变量

​ var声明语句可以创建一个特定类型的变量,然后给变量附加一个名字,并且设置变量的初始值。变量声明的一般语法如下:

var varName varType = expr

其中“类型”或“= 表达式”两个部分可以省略其中的一个。如果省略的是类型信息,那么将根据初始化表达式来推导变量的类型信息。如果初始化表达式被省略,那么将用零值初始化该变量。

​ 变量在函数内和函数外的声明形式有所不同,基本声明方式如下:

//可以声明相同类型的变量,也可以声明不同类型的变量
var i, j, k int                 // int, int, int
var b, f, s = true, 2.3, "four" // bool, float64, string

//自动类型推导
freq := rand.Float64() * 3.0
t := 0.0

//var形式的声明语句往往是用于需要显式指定变量类型的地方,或者因为变量稍后会被重新赋值而初始值无关紧要的地方。
var boiling float64 = 100 // a float64
var names []string
var err error
var p Point

//“:=”是一个变量声明语句,而“=”是一个变量赋值操作
f, err := os.Open(name)
if err != nil {
    return err
}
// ...use f...
f.Close()

​ 变量的创建还可以通过new函数。表达式new(T)将创建一个T类型的匿名变量,初始化为T类型的零值,然后返回变量地址,返回的指针类型为*T

p := new(int)   // p, *int 类型, 指向匿名的 int 变量
fmt.Println(*p) // "0"
*p = 2          // 设置 int 匿名变量的值为 2
fmt.Println(*p) // "2"

结构体

​ 在go语言中,结构体通过type来定义,并且可以为其初始化和创建结构体方法。

type user struct{
	name string
	password string
}

//定义成员方法
func (u user) checkPassword(password string)bool{
	return u.password == password
}
func (u *user) checkPassword1(password string)bool{
	return u.password == password
}

func structMain(){
	//初始化
	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(checkPassword1(&b, "hehe"))
	fmt.Println(a.checkPassword("hahe"))
}

切片和map处理

​ 切片和map是go最常见的数据结构,其初始化和基本使用如下:

//切片
func slice(){
	fmt.Println("123")
	s := make([]string, 3)
	s[0] = "a"
	s[1] = "b"
	s[2] = "c"
	s = append(s, "123")
	fmt.Println(s)
	c := make([]string, len(s))
	copy(c, s)
	fmt.Println(c)
	good := []string{"g", "o", "o", "d"}
	fmt.Println(good)
}

func mapFunc(){
	m := make(map[string]int)
	m["one"] = 1
	fmt.Println(m["unknow"]) // 0
	r, ok := m["unknow"]
	fmt.Println(r, ok) // 0 false
	delete(m, "one")
}

遍历

​ 通常采用for range语句来进行遍历,如果是切片或者数组,会返回下标和值,如果是map的话,会直接返回key和value。

func rangeTest(){
	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 k:= range m{
		fmt.Println("key", k)
	}

}

常用包

json处理

​ 与C++不同,go可以通过导入"encoding/json"包,直接对json文件进行处理。

type userInfo struct{
	Name string
	Age int `json:"age"` //使输出类型变成小写
	Hobby []string
}

func jsonMain(){
	a := userInfo{"wang", 18, []string{"Golang", "C++"}}
	buf, err := json.Marshal(a)
	if err != nil{
		panic(err)
	}

	fmt.Println(buf) //必须进行类型转换
	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)
}

时间处理

​ go通过导入"time"包来对时间进行处理

func timeMain(){
	//获取当前时间
	now := time.Now()
	fmt.Println(now)

	t := time.Date(2022, 5, 9, 10, 1, 0, 0,time.UTC)
	t1 := time.Date(2022, 5, 9, 10, 2, 1, 0,time.UTC)
	fmt.Println(t) // 2022-05-09 10:01:00 +0000 UTC
	fmt.Println(t1.Year(), t1.Month(), t1.Day(), t1.Hour(), t1.Minute())
	fmt.Println(t.Format("2020-01-01 00:00:00")) //以这个格式输出
	diff := t1.Sub(t) //计算t 和 t1之间的时差
	fmt.Println(diff)
	fmt.Println(diff)
	fmt.Println(diff.Minutes(), diff.Seconds())

	t3, err := time.Parse("2006-01-02 15:04:03", "2022-05-9 10:01:00")
	if err != nil{
		panic(err)
	}
	fmt.Println(t3 == t) //true
	fmt.Println(now.Unix()) //获取时间戳
}

字符解析

​ 通过导入“strconv”包对字符进行解析

func numParseMain(){
	// _用于占位一个错误输出
	f, _ := strconv.ParseFloat("1.234", 64)
	fmt.Println(f) //1.234

	//第二个参数表示进制,0表示自动推测
	n, _ := strconv.ParseInt("111", 10, 64)
	fmt.Println(n) // 111

	n1, _ := strconv.ParseInt("0x1000", 0, 64)
	fmt.Println(n1)

	n2, _ := strconv.Atoi("1234")
	fmt.Println(n2)

}

输入

​ go通过“bufio”包来处理用户输入

func readFromInput(){
	//获取输入
	counts := make(map[string]int)
	inputs := bufio.NewScanner(os.Stdin)
	for inputs.Scan() {
		counts[inputs.Text()]++
		if inputs.Text() == "q!" {
			break
		}
	}
	for line, n := range counts{
		if n >= 1{
			fmt.Printf("%d\t%s\n", n, line)
		}
	}
}

文件输入

​ 除了获取用户输入外,还可以通过“os”包获取文件输入

func readFromFile(){
	//从文件中读取
	counts_ := make(map[string]int)
	files := os.Args[1:]
	if len(files) == 0{
		countLines(os.Stdin, counts_)
	}else{
		for _, arg := range files{
			f, err := os.Open(string(arg))
			if err != nil{
				fmt.Fprintf(os.Stderr, "dup2: %v\n", err)
				continue
			}
			countLines(f, counts_)
			f.Close()
		}
	}

	for line, n := range counts_{
		if n >= 1{
			fmt.Printf("key = %s, value = %d\n", line, n)
		}
	}
}

func countLines(f *os.File, counts map[string]int){
	input := bufio.NewScanner(f)
	for input.Scan(){
		counts[input.Text()]++
	}
}

错误处理

​ 在go中,遍历以及函数返回等都可以返回错误,方便处理。

//错误处理
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 errorMain(){
	u, err := findUser([]user{{"wang", "1024"}}, "wang")
	if err != nil{
		fmt.Println(err)
		return
	}
	fmt.Println(u.name)

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

基本学习的代码总览

package main

import (
	"bufio"
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"os/exec"
	"strconv"
	"time"
)

//结构体
type user struct{
	name string
	password string
}

//定义成员方法
func (u user) checkPassword(password string)bool{
	return u.password == password
}
func (u *user) checkPassword1(password string)bool{
	return u.password == password
}

func structMain(){
	//初始化
	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(checkPassword1(&b, "hehe"))
	fmt.Println(a.checkPassword("hahe"))
}

//传值
func checkPassword(u user, password string)bool{
	return u.password == password
}
//传指针
func checkPassword1(u *user, password string)bool{
	return u.password == password
}

func main() {
	//slice()
	//rangeTest()
	//structMain()
	//errorMain()
	//jsonMain()
	processInfoMain()
}
//获取进程相关信息
func processInfoMain(){
	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))
}


//字符解析
func numParseMain(){
	// _用于占位一个错误输出
	f, _ := strconv.ParseFloat("1.234", 64)
	fmt.Println(f) //1.234

	//第二个参数表示进制,0表示自动推测
	n, _ := strconv.ParseInt("111", 10, 64)
	fmt.Println(n) // 111

	n1, _ := strconv.ParseInt("0x1000", 0, 64)
	fmt.Println(n1)

	n2, _ := strconv.Atoi("1234")
	fmt.Println(n2)



}

//时间处理
func timeMain(){
	//获取当前时间
	now := time.Now()
	fmt.Println(now)

	t := time.Date(2022, 5, 9, 10, 1, 0, 0,time.UTC)
	t1 := time.Date(2022, 5, 9, 10, 2, 1, 0,time.UTC)
	fmt.Println(t) // 2022-05-09 10:01:00 +0000 UTC
	fmt.Println(t1.Year(), t1.Month(), t1.Day(), t1.Hour(), t1.Minute())
	fmt.Println(t.Format("2020-01-01 00:00:00")) //以这个格式输出
	diff := t1.Sub(t) //计算t 和 t1之间的时差
	fmt.Println(diff)
	fmt.Println(diff)
	fmt.Println(diff.Minutes(), diff.Seconds())

	t3, err := time.Parse("2006-01-02 15:04:03", "2022-05-9 10:01:00")
	if err != nil{
		panic(err)
	}
	fmt.Println(t3 == t) //true
	fmt.Println(now.Unix()) //获取时间戳
}

//错误处理
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 errorMain(){
	u, err := findUser([]user{{"wang", "1024"}}, "wang")
	if err != nil{
		fmt.Println(err)
		return
	}
	fmt.Println(u.name)

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

//json处理
type userInfo struct{
	Name string
	Age int `json:"age"` //使输出类型变成小写
	Hobby []string
}

func jsonMain(){
	a := userInfo{"wang", 18, []string{"Golang", "C++"}}
	buf, err := json.Marshal(a)
	if err != nil{
		panic(err)
	}

	fmt.Println(buf) //必须进行类型转换
	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)
}




//切片
func slice(){
	fmt.Println("123")
	s := make([]string, 3)
	s[0] = "a"
	s[1] = "b"
	s[2] = "c"
	s = append(s, "123")
	fmt.Println(s)
	c := make([]string, len(s))
	copy(c, s)
	fmt.Println(c)
	good := []string{"g", "o", "o", "d"}
	fmt.Println(good)
}

func mapFunc(){
	m := make(map[string]int)
	m["one"] = 1
	fmt.Println(m["unknow"]) // 0
	r, ok := m["unknow"]
	fmt.Println(r, ok) // 0 false
	delete(m, "one")
}

func rangeTest(){
	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 k:= range m{
		fmt.Println("key", k)
	}

}


func readFromArgs(){
	fmt.Printf("%s\n", os.Args[0])
	//s, sep := "", ""
	for i, arg := range os.Args[1:] {
		fmt.Printf("item = %d, value = %s\n", i, arg)
		//s += sep + arg
		//sep = " "
	}
	//fmt.Println(s)
}


func readFromInput(){
	//获取输入
	counts := make(map[string]int)
	inputs := bufio.NewScanner(os.Stdin)
	for inputs.Scan() {
		counts[inputs.Text()]++
		if inputs.Text() == "q!" {

			break
		}
	}
	for line, n := range counts{
		if n >= 1{
			fmt.Printf("%d\t%s\n", n, line)
		}
	}
}

func readFromFile(){
	//从文件中读取
	counts_ := make(map[string]int)
	files := os.Args[1:]
	if len(files) == 0{
		countLines(os.Stdin, counts_)
	}else{
		for _, arg := range files{
			f, err := os.Open(string(arg))
			if err != nil{
				fmt.Fprintf(os.Stderr, "dup2: %v\n", err)
				continue
			}
			countLines(f, counts_)
			f.Close()
		}
	}

	for line, n := range counts_{
		if n >= 1{
			fmt.Printf("key = %s, value = %d\n", line, n)
		}
	}
}

func countLines(f *os.File, counts map[string]int){
	input := bufio.NewScanner(f)
	for input.Scan(){
		counts[input.Text()]++
	}
}

猜数字游戏

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("The secret number is", secretNumber)

	for i := 10; i >0; i--{
		fmt.Println("Please input your guess")
		reader := bufio.NewReader(os.Stdin)
		input, err := reader.ReadString('\n')
		if err != nil{
			fmt.Println("An error occured whild reading input, Please try again", err)
			continue
		}
		input = strings.Trim(input, "\n") //去除换行符
		guess, err := strconv.Atoi(input)
		if err != nil{
			fmt.Println("Invalid input, Please enter an integer value")
			continue
		}
		fmt.Println("Your guess is ", guess)

		if(guess == secretNumber){
			fmt.Println("your guess is right !")
			return
		}else if(guess > secretNumber){
			fmt.Println("the number you guess is bigger than secretNumber, please try again")
			continue
		}else{
			fmt.Println("the number you guess is smaller than secretNumber, please try again")
		}
	}
    fmt.Println("you loss this game!")
    
}

Sockets5代理服务器

package main

import (
	"bufio"
	"context"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"log"
	"net"
)

const socks5Ver = 0x05
const cmdBind = 0x01
const atypIPV4 = 0x01
const atypeHOST = 0x03
const atypeIPV6 = 0x04

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)
	err := auth(reader, conn)
	if err != nil {
		log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err)
		return
	}
	err = connect(reader, conn)
	if err != nil {
		log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err)
		return
	}
}

func auth(reader *bufio.Reader, conn net.Conn) (err error) {
	// +----+----------+----------+
	// |VER | NMETHODS | METHODS  |
	// +----+----------+----------+
	// | 1  |    1     | 1 to 255 |
	// +----+----------+----------+
	// VER: 协议版本,socks5为0x05
	// NMETHODS: 支持认证的方法数量
	// METHODS: 对应NMETHODS,NMETHODS的值为多少,METHODS就有多少个字节。RFC预定义了一些值的含义,内容如下:
	// X’00’ NO AUTHENTICATION REQUIRED
	// X’02’ USERNAME/PASSWORD

	ver, err := reader.ReadByte()
	if err != nil {
		return fmt.Errorf("read ver failed:%w", err)
	}
	if ver != socks5Ver {
		return fmt.Errorf("not supported ver:%v", ver)
	}
	methodSize, err := reader.ReadByte()
	if err != nil {
		return fmt.Errorf("read methodSize failed:%w", err)
	}
	method := make([]byte, methodSize)
	_, err = io.ReadFull(reader, method)
	if err != nil {
		return fmt.Errorf("read method failed:%w", err)
	}

	// +----+--------+
	// |VER | METHOD |
	// +----+--------+
	// | 1  |   1    |
	// +----+--------+
	_, err = conn.Write([]byte{socks5Ver, 0x00})
	if err != nil {
		return fmt.Errorf("write failed:%w", err)
	}
	return nil
}

func connect(reader *bufio.Reader, conn net.Conn) (err error) {
	// +----+-----+-------+------+----------+----------+
	// |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
	// +----+-----+-------+------+----------+----------+
	// | 1  |  1  | X'00' |  1   | Variable |    2     |
	// +----+-----+-------+------+----------+----------+
	// VER 版本号,socks5的值为0x05
	// CMD 0x01表示CONNECT请求
	// RSV 保留字段,值为0x00
	// ATYP 目标地址类型,DST.ADDR的数据对应这个字段的类型。
	//   0x01表示IPv4地址,DST.ADDR为4个字节
	//   0x03表示域名,DST.ADDR是一个可变长度的域名
	// DST.ADDR 一个可变长度的值
	// DST.PORT 目标端口,固定2个字节

	buf := make([]byte, 4)
	_, err = io.ReadFull(reader, buf)
	if err != nil {
		return fmt.Errorf("read header failed:%w", err)
	}
	ver, cmd, atyp := buf[0], buf[1], buf[3]
	if ver != socks5Ver {
		return fmt.Errorf("not supported ver:%v", ver)
	}
	if cmd != cmdBind {
		return fmt.Errorf("not supported cmd:%v", ver)
	}
	addr := ""
	switch atyp {
	case atypIPV4:
		_, err = io.ReadFull(reader, buf)
		if err != nil {
			return fmt.Errorf("read atyp failed:%w", err)
		}
		addr = fmt.Sprintf("%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3])
	case atypeHOST:
		hostSize, err := reader.ReadByte()
		if err != nil {
			return fmt.Errorf("read hostSize failed:%w", err)
		}
		host := make([]byte, hostSize)
		_, err = io.ReadFull(reader, host)
		if err != nil {
			return fmt.Errorf("read host failed:%w", err)
		}
		addr = string(host)
	case atypeIPV6:
		return errors.New("IPv6: no supported yet")
	default:
		return errors.New("invalid atyp")
	}
	_, err = io.ReadFull(reader, buf[:2])
	if err != nil {
		return fmt.Errorf("read port failed:%w", err)
	}
	port := binary.BigEndian.Uint16(buf[:2])

	dest, err := net.Dial("tcp", fmt.Sprintf("%v:%v", addr, port))
	if err != nil {
		return fmt.Errorf("dial dst failed:%w", err)
	}
	defer dest.Close()
	log.Println("dial", addr, port)

	// +----+-----+-------+------+----------+----------+
	// |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
	// +----+-----+-------+------+----------+----------+
	// | 1  |  1  | X'00' |  1   | Variable |    2     |
	// +----+-----+-------+------+----------+----------+
	// VER socks版本,这里为0x05
	// REP Relay field,内容取值如下 X’00’ succeeded
	// RSV 保留字段
	// ATYPE 地址类型
	// BND.ADDR 服务绑定的地址
	// BND.PORT 服务绑定的端口DST.PORT
	_, err = conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0})
	if err != nil {
		return fmt.Errorf("write failed: %w", err)
	}

	//创建context层
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	//开启两个子线程,等待任意一个结束
	go func() {
		_, _ = io.Copy(dest, reader)
		cancel()
	}()
	go func() {
		_, _ = io.Copy(conn, dest)
		cancel()
	}()

	//等待context层结束
	<-ctx.Done()
	return nil
}

在线词典

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{}
	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("Connection", "keep-alive")
	req.Header.Set("DNT", "1")
	req.Header.Set("os-version", "")
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36")
	req.Header.Set("app-name", "xy")
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	req.Header.Set("Accept", "application/json, text/plain, */*")
	req.Header.Set("device-id", "")
	req.Header.Set("os-type", "web")
	req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi")
	req.Header.Set("Origin", "https://fanyi.caiyunapp.com")
	req.Header.Set("Sec-Fetch-Site", "cross-site")
	req.Header.Set("Sec-Fetch-Mode", "cors")
	req.Header.Set("Sec-Fetch-Dest", "empty")
	req.Header.Set("Referer", "https://fanyi.caiyunapp.com/")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")
	req.Header.Set("Cookie", "_ym_uid=16456948721020430059; _ym_d=1645694872")
	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)
	}
	
	//防止返回空结构
	if resp.StatusCode != 200 {
		log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))
	}
	var dictResponse DictResponse
	err = json.Unmarshal(bodyText, &dictResponse)
	if err != nil {
		log.Fatal(err)
	}
	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)
}

参考文献

​ 本文代码均来自于字节青训项目第一节课。

你可能感兴趣的:(秋招日记,golang,学习,开发语言)