《Go 语言上手-基础语言》:guessing-game代码解析与相关函数详解 | 青训营笔记

228 阅读4分钟

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

一、函数

1. func Seed(seed int64) 设置随机数种子

如果没有设置,就默认rang.Seed(1),相同的随机数种子会生成相同的伪随机数数列。 所以可以rand.seed(time.Now().UnixNano())来通过当前时间给一个随机数种子

2. func Now() Time :返回当前时间

但是注意time类型无法直接fmt输出,需要转化为string

  • time.Now().String() : 2022-05-09 14:58:28.520221483 +0800 CST m=+0.001279989
  • time.Now().UnixNano() : 从1970年1月1日到现在的纳秒数
    • 同理.Unix()是秒数
    • .UnixMicro()微秒
    • .UnixMilli()毫秒

3.

  • func NewReader(rd io.Reader) *Reader :通过文件句柄返回一个reader,可以用这个reader进行读操作 例如:

    reader := bufio.NewReader(os.Stdin)

    打开一个标准输入流

  • func (b *Reader) ReadString(delim byte) (string, error) :读取reader中的内容,直到出现delim字符,注意delim字符也会被读进去 例如:

    reader.ReadString('\n')

    reader是上边打开的标准输入流,从标准输入流读取数据,直到碰见换行符。

完整案例:

这样会从标准输入流中获取数据,直到出现换行符,同时换行符也会被读进去。

reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
  • 如果想从其他的输入流,例如文件中获取,则可以通过 file, err := os.Open("xxx") 来打开一个文件,获取文件的句柄 然后用file代替上文的os.Stdin
file, _ := os.Open("./1.txt")
reader := bufio.NewReader(file)
f, _ := reader.ReadString('1')
fmt.Println(f)
1.txt

918736515453

输出:
91

4. func TrimSuffix(s, suffix string) string : 如果s最后是suffix字符串,那么删去,如果不是,没变化

一般是用来处理上边的ReadString最后剩下的结尾,注意suffix是一个string

例如可以这样

reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
input = strings.TrimSuffix(input, "\n")

5. 字符串转数字:

  • func Atoi(s string) (int, error) 等同于ParseInt(s, 10, 0)
  • func ParseInt(s string, base int, bitSize int) (i int64, err error) 字符串转为int类型的数字:
    • 第一个参数是需要转换的字符串
    • 第二个参数是字符串代表的进制数。注意是字符串本身的进制,可选的是0,2~36,如果输入0,那么默认根据字符串前缀来判断是什么进制
    • 第三个参数是转化后的数字的必须合适的类型,0,8,16,32,64分别代表int,int8, int16,int32,int64。但是需要注意的是,返回值永远是int64类型
  • func ParseFloat(s string, bitSize int) (float64, error) 字符串转为浮点数类型的数字,参数含义同上。

例如:

    va := "10"
	if s, err := strconv.Atoi(va); err == nil {
		fmt.Printf("%T, %v", s, s)
	}
    v32 := "-354634382"
	if s, err := strconv.ParseInt(v32, 10, 32); err == nil {
		fmt.Printf("%T, %v\n", s, s)
	}
    vf := "3.1415926535"
	if s, err := strconv.ParseFloat(vf, 32); err == nil {
		fmt.Printf("%T, %v\n", s, s)
	}   

6. 如果只是想从标准输入中获取信息,可以使用fmt.Scranf来简化输入

func Scanf(format string, a ...any) (n int, err error) 其中format是输入的格式, 后边是负责接受的变量 例如:

    var name string
	var age byte
	var salary float32
	var isOffer bool

	fmt.Println("请输入您的姓名, 年龄,薪水,是否拿到offer")
	fmt.Scanf("%s %d %f %t", &name, &age, &salary, &isOffer)
    fmt.Printf("姓名:%v\n 年龄:%v\n 薪水:%v\n 是否拿到offer:%v\n", name, age, salary, isOffer)

//输出
// 输出结果
请输入您的姓名, 年龄,薪水,是否拿到offer
fe_cow 18 123.123 true
姓名:fe_cow
 年龄:18
 薪水:123.123
 是否拿到offer:true

注意格式也是可以变化的,例如:

fmt.Scanf("%s:%d:%f:%t", &name, &age, &salary, &isOffer)
则需要这样输入才会被正确读取
fe_cow:18:123.123:true

如果中间没有空格,例如fmt.Scanf("%s%d%f%t", &name, &age, &salary, &isOffer)则默认输入的时候也是要加空格的

二、完整代码+解析:v5版本

package main

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

func main() {

	//生成一个随机数
	//func Seed(seed int64) 设置随机数种子
	//time.Now()返回当前时间,调用UnixNano返回从”那个时间“到现在为止的纳秒数,是一个int64类型的数值
	rand.Seed(time.Now().UnixNano())

	//设置随机数的上界
	maxNum := 100

	//返回[0, n)之间的int类型的随机数,如果输入的n小于等于0,会panic
	secretNumber := rand.Intn(maxNum)
	// fmt.Println("The secret number is ", secretNumber)

	fmt.Println("Please input your guess")
	//bufio包用于I/O,bufio.NewReader(io.Reader)使用句柄,返回一个*Reader,可以用于读取数据
	//这个语句的意思就是打开一个标准输入流
	reader := bufio.NewReader(os.Stdin)
	for {
		//reader.ReadString(delim)一直读取直到出现delim字符
		input, err := reader.ReadString('\n')
		//err不等于nil,说明读取失败
		if err != nil {
			fmt.Println("An error occured while reading input. Please try again", err)
			continue
		}

		//把尾后的"\n"字符删去
		input = strings.TrimSuffix(input, "\n")

		//把字符串转化为int数字,类似于strconv.ParseInt(a, 10, 0)
		guess, err := strconv.Atoi(input)
		if err != nil {
			fmt.Println("Invalid input. Please enter an integer value")
			continue
		}
		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!")
			break
		}
	}
}

三、课后题修改Scanf

package main

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

func main() {

	//生成一个随机数
	//func Seed(seed int64) 设置随机数种子
	//time.Now()返回当前时间,调用UnixNano返回从”那个时间“到现在为止的纳秒数,是一个int64类型的数值
	rand.Seed(time.Now().UnixNano())

	//设置随机数的上界
	maxNum := 100

	//返回[0, n)之间的int类型的随机数,如果输入的n小于等于0,会panic
	secretNumber := rand.Intn(maxNum)
	// fmt.Println("The secret number is ", secretNumber)

	fmt.Println("Please input your guess")
	//bufio包用于I/O,bufio.NewReader(io.Reader)使用句柄,返回一个*Reader,可以用于读取数据
	//这个语句的意思就是打开一个标准输入流
	for {
		//reader.ReadString(delim)一直读取直到出现delim字符
		var guess int
		_, err := fmt.Scanf("%d", &guess)
		if err != nil {
			fmt.Println("An error occured while reading input. Please try again", err)
			continue
		}
		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!")
			break
		}
	}
}