后端课程记录 | 青训营笔记

77 阅读4分钟

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

声明:由于小伙伴们已经写了很多优秀的笔记,本文不涉及基础语法的单独讲解。介意者勿怪。

引言: Go语言全称为Golang,是Google公司自主研发的一款开源编程语言。Go 编程语言构思于 2007 年底,根据在早期的采访中,Google 大佬们反馈感觉 "编程" 太麻烦了,他们很不喜欢 C++,对于现在工作所用的语言和环境感觉比较沮丧,充满着许多不怎么好用的特性,因此Go语言应运而生。

f356b647cf62d5e51a57e18f03b6858.png (由左至右依次为Robert Griesemer,Rob Pike和Ken Thompson都是大牛中的大牛)

一、按照惯例,入门Go先打个招呼

package main  
  
import "fmt"  
  
func main() {  

   fmt.Println("Hello, Go!")  
}

其中,

  1. package是用来定义包名字的。Go语言是使用包来组织编码的,也就是说每个程序你想被编译运行,就得有自己的包名字。并且还要满足以下条件。

    • 一个程序只能有一个main函数,他是Go语言程序的入口函数,且必须属于main包,没有或者多于一个进行Go语言程序编译时都会报错
    • 同一个目录下的所有go文件应该属于一个包
  2. 包首先需要被导入才能使用包中的导出标识符,就像C系列的include

  3. Println就属于包fmt

二、详细知识点介绍

基础语法在Github上或各大资源网站都有,我们直接看入门项目。在执行中学习。

三、实践练习例子:

  1. 猜数字(系统设定数字我循环猜,直到猜中结束)

    要点如下

    • 生成随机的数字
    • 读入我的输入
    • 对比输入与随机数并且循环

a. 生成随机数

func main() {
   maxNum := 100
   rand.Seed(time.Now().UnixNano())
   secretNumber := rand.Intn(maxNum)
   fmt.Println("The secret number is ", secretNumber)
}

先设定随机范围最大值为100,然后根据时间戳设定随机数种子。逻辑如下:没time.Now()--->没随机数种子--->每次的随机值都是一样的--->不能达到得到随机种子的目标。

这时候疑问来了,UnixNano()什么?简单理解就是得到的是int64形式的时间,因为rand.Seed就需要int64的输入。

b. 读入我的输入

import (
   "bufio"
   "fmt"
   "math/rand"
   "os"
   "strconv"
   "strings"
   "time"
)
//节选
......
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.TrimSuffix(input, "\n")
......

加了几个需要的包,但是主要读入的代码如上。reader := bufio.NewReader(os.Stdin)如何理解?os.Stdin显然和C++类似都是用来读入输入的。这里的bufio是读入文件的一种方式所用到的包之一,其中的NewReader就是用来读取文件内容的。但是此时的文件是我们的输入,也可以看作是文件。

c. 对比输入与随机数并且循环

image.png 代码太多了,其实逻辑已经在b中展示过了。无非就是加了一层循环,循环中加了一个判断输入的代码。

image.png 值得注意的是在使用curlconverter网站进行生成代码时,需要复制的是bash格式的url而不是cmd格式的(我用的谷歌)主要代码如下:

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

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

其中,data是一个流,一般的输入为字符串也会转换成一个流,以防止body太大,传输出错成本过大的情况。

defer需要在确定有无错误后立即关闭整个资源的流,以防止资源的泄露。流程顺着老师的来就能有大致的理解了。

第三个实验属实是超纲了,暂且挖个坑以后更新。

四、课后个人总结:

  • 有关于网络编程部分不是很容易掌握,我们需要十分小心Socket的设计细节
  • 代码要多调试,多分析为什么这一步行,不能想当然

五、引用参考:

  • 字节青训营Go语法基础课