这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
声明:由于小伙伴们已经写了很多优秀的笔记,本文不涉及基础语法的单独讲解。介意者勿怪。
引言: Go语言全称为Golang,是Google公司自主研发的一款开源编程语言。Go 编程语言构思于 2007 年底,根据在早期的采访中,Google 大佬们反馈感觉 "编程" 太麻烦了,他们很不喜欢 C++,对于现在工作所用的语言和环境感觉比较沮丧,充满着许多不怎么好用的特性,因此Go语言应运而生。
(由左至右依次为Robert Griesemer,Rob Pike和Ken Thompson都是大牛中的大牛)
一、按照惯例,入门Go先打个招呼
package main
import "fmt"
func main() {
fmt.Println("Hello, Go!")
}
其中,
-
package是用来定义包名字的。Go语言是使用包来组织编码的,也就是说每个程序你想被编译运行,就得有自己的包名字。并且还要满足以下条件。
- 一个程序只能有一个
main函数,他是Go语言程序的入口函数,且必须属于main包,没有或者多于一个进行Go语言程序编译时都会报错 - 同一个目录下的所有go文件应该属于一个包
- 一个程序只能有一个
-
包首先需要被导入才能使用包中的导出标识符,就像C系列的include
-
Println就属于包fmt
二、详细知识点介绍
基础语法在Github上或各大资源网站都有,我们直接看入门项目。在执行中学习。
三、实践练习例子:
-
猜数字(系统设定数字我循环猜,直到猜中结束)
要点如下
- 生成随机的数字
- 读入我的输入
- 对比输入与随机数并且循环
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. 对比输入与随机数并且循环
代码太多了,其实逻辑已经在b中展示过了。无非就是加了一层循环,循环中加了一个判断输入的代码。
值得注意的是在使用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语法基础课