这是我参与「第三届青训营 -后端场」笔记创作活动的的第 1 篇笔记
前言
在猜词小游戏当中,我看到 示例源码 的输入处理方式是使用 bufio.NewReader 来做的。
其实 golang 一般的输入方式是用 scanf 函数,与 c/c++ 的 scanf 类似
fmt 输入
fmt.Scan
fmt.Scan
交互式接受输入,通过空格来分词。调用Scan函数时,要指定接收输入的变量名和变量数。
直到接收完所有指定的变量数,Scan函数才会返回,回车符也无法提前让它返回。
func main() {
var (
num int
name string
)
fmt.Scan(&num, &name)
fmt.Println(num, name)
}
fmt.Scanln
Scanln
调用时,也要指定接收输入的变量名和变量数。
它同Scan的区别,在于\ n
会让函数提前返回,将返回时还未接收到值的变量赋为空。
func main() {
var bfirstName, bsecondName string
fmt.Println("Please enter the firstName and secondName: ")
fmt.Scanln(&bfirstName, &bsecondName)
fmt.Printf("firstName is %s, secondName is %s\n", bfirstName, bsecondName)
}
Please enter the firstName and secondName:
de
firstName is de, secondName is
fmt.Scanf
用Scanf
处理输入,是比较灵活的一种处理方式。
需要指定输入的格式,适用于完全了解输入格式的场景,可以直接把不需要的部分过滤掉。
fmt.Println("Please enter the firstName and secondName: ")
fmt.Scanf("//%s\n%s", &cfirstName, &csecondName)
fmt.Printf("firstName is %s, secondName is %s", cfirstName, csecondName)
结果如下:
1)这个场景,在接收输入时,就把不需要的部分“//” 和 “\n”过滤掉了,接收到是有用的两个字符串zz和rr。
Please enter the firstName and secondName:
//zz
rr
firstName is zz, secondName is rr
2)如果输入不符合指定的格式,从不符合处开始,其后的变量值都为空。
Please enter the firstName and secondName:
//zr ui
firstName is zr, secondName is
bufio 输入
简介
bufio:从 buf 前缀可以看出,这是一个与 buffer (缓冲) 相关的 IO 操作标准库
可以类比 Java 的 "BufferedReaderStream and BufferedWriterStream"[^1]
通过缓冲来提高读写效率
- io操作本身的效率并不低,低的是频繁的访问本地磁盘的文件。所以bufio就提供了缓冲区(分配一块内存),读和写都先在缓冲区中,最后再读写文件,来降低访问本地磁盘的次数,从而提高效率。
简单的说就是,把文件读取进缓冲(内存)之后再读取的时候就可以避免文件系统的io 从而提高速度。同理,在进行写操作时,先把文件写入缓冲(内存),然后由缓冲写入文件系统。
缓冲区的设计是为了存储多次的写入,最后一口气把缓冲区内容写入文件。
bufio 封装了io.Reader或io.Writer接口对象,并创建另一个也实现了该接口的对象。
以下简单说一下如何使用
io.Reader
bufio 包提供了两个实例化 bufio.Reader 对象的函数:NewReader 和 NewReaderSize。其中,NewReader 函数是调用 NewReaderSize 函数实现的:
func NewReader(rd io.Reader) *Reader {
// 默认缓存大小:defaultBufSize=4096
return NewReaderSize(rd, defaultBufSize)
}
我们先创建一个 reader,然后调用里面的方法
- 可以看到,读取的方法很多
猜字游戏中使用的是 ReadString 方法
func main() {
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil {
panic(errors.New("输入失败"))
}
fmt.Println(input)
}
- readString 中输入的参数是 delim:表示用什么字符进行划分
- \n 表示用空格进行划分字符
io.Writer
writer 主要用于写文件操作
示例代码
func main() {
var (
fileName = "D:/test.txt"
content = "Hello golang"
file *os.File
err error
)
// 使用追加模式打开文件
file, err = os.OpenFile(fileName, os.O_APPEND, 0666)
if err != nil {
panic(errors.New("打开文件失败"))
}
defer file.Close() // 养成好习惯,打开资源后紧跟着defer关闭
// 写文件
writer := bufio.NewWriter(file)
n, err := writer.Write([]byte(content))
if err != nil {
panic(errors.New("写入文件失败"))
}
fmt.Println("写入文件成功,文件长度为 = ", n)
writer.Flush() // 刷新
}
小结
以上只是做作业过程中的临时记录,后面有时间会补充缺失的内容