初识Golang | 青训营笔记

89 阅读2分钟

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

课前准备

参与本次青训营是我第一次学习Go语言,因此肯定要在我的电脑上搭载环境,由此也引发了一些问题。

由于我是VScode安装Go拓展插件的方式来搭载环境的,因此刚开始时发现拓展插件总是安装失败,后来找到了对应解决方法如下:

1.在Windows下打开cmd,输入下面语句

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

2.重新打开VScode,即可安装成功

本堂课重点内容

1.go语言的语言基础

2.通过go语言进行项目实战

详细知识点

语法

我平时最常用的语言是C++,学习go语言我能感受到二者很多相同和不同之处

在go中我们可以看到熟悉的引入标准库,变量,循环语句和条件选择语句,但是又做了很多不同程度的升级和简化,并且提供的垃圾回收功能,是Go程序员相比于C++程序员可以花更少的时间在内存回收上,更加专注于业务逻辑

变量

变量的定义变得更为方便,既可以直接用 var 定义变量,直接根据所赋予的数据判断数据类型,也可以在变量后加上确定的数据类型

循环语句

在go中只存在一种循环语句,那就是for循环,但是for循环的使用变得更为多样和方便,除了像c++原本for循环的用法外,也可以像使用while一样使用它

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

选择语句

if和Switch语句也在Go中得到了升级,特别是switch语句,在go中不用一坑一个break,更是可以像if语句一样进行更多的条件判定

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

一些实用的小工具

比如curl转go/java等语言的工具,还有Json转Go的工具

这些实用的工具网站极大的增加了我们的开发速度,降低了开发门槛

实践练习例子

猜数字小游戏

该项目主要是为了熟悉go语言的语法,逻辑简单,易于上手。做完一边能对golang的基本语法存在基本印象

    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)

	fmt.Println("Please input your guess")
	reader := bufio.NewReader(os.Stdin)
	input, err := reader.ReadString('\n')
	if err != nil {
		fmt.Println("An error occured while reading input. Please try again", err)
		return
	}
	input = strings.Trim(input, "\r\n")

	guess, err := strconv.Atoi(input)
	if err != nil {
		fmt.Println("Invalid input. Please enter an integer value")
		return
	}
	fmt.Println("You 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!")
	}
}

在线词典

除开go语言,还融合了部分网络以及json方面的知识,同时在该项目的实践中,学会使用了两个线上工具来帮助开发

    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,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
	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", "Microsoft Edge";v="109", "Chromium";v="109"`)
	req.Header.Set("sec-ch-ua-mobile", "?1")
	req.Header.Set("sec-ch-ua-platform", `"Android"`)
	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 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36 Edg/109.0.1518.52")
	req.Header.Set("x-authorization", "token:qgemv4jr1y38jyq6vhvi")
	//发起请求
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close() //为了防止resp.body的这个流泄露,需要主动关闭
	//读取响应
	bodyText, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	if resp.StatusCode != 200 {
		log.Fatal("bad StatusCod:", resp.StatusCode, "body", string(bodyText))
	}
	//fmt.Printf("%s\n", 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, `usege: simpleDict WORD example: simpleDict hello`)
		os.Exit(1)
	}
	word := os.Args[1]
	query(word)
}

网络代理

由于网络基础薄弱,该段内容比较模糊

在VScode中开发的问题

当用调试控制台输入时,显示了这样的错误:

Unable to process evaluate : debuggee is running

但是在终端中输入就没有这个问题

作业部分

用fmt.Scanf简化代码

fmt.Scanf不管怎么看都很像C语言中的标准输入scanf,运用起来的语法也是一样的,但是 值得注意的是,在第一次用fmt.Scanf的时候,会把回车换行也给读取进去,导致下一次读取数据失败,解决方法也很简单,fmt.Scanf的下一行添加fmt.Scanln即可,就像C语言中添加getchar()一样

    package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	maxNum := 100                    //设置随机出来最大数字
	rand.Seed(time.Now().UnixNano()) //以当前时间戳作为随机数种子
	secretNumber := rand.Intn(maxNum)
	fmt.Println(secretNumber)

	for {
		fmt.Println("plaese input number you guess")

		var guess int
		_, err := fmt.Scanf("%d", &guess)
		fmt.Scanln()
		fmt.Println("you guess is", guess)
		if err != nil {
			fmt.Println("invalid input. Please enter an integer value")
			return
		}
		if guess == secretNumber {
			fmt.Println("Success! The secretNumber is: ", secretNumber)
			break
		} else if guess > secretNumber {
			fmt.Println("your input is bigger,try it again")
		} else {
			fmt.Println("you input is smaller,try it again")
		}
	}
}

增加命令行词典中的另一种翻译引擎的支持