mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-11 23:08:34 +08:00
阅读并校对12.1 到 12.7
This commit is contained in:
Binary file not shown.
@@ -45,7 +45,7 @@ func main() {
|
||||
|
||||
**注意:** 在之前的例子中,我们看到,Unix和Linux的行结束符是 \n,而Windows的行结束符是 \r\n。在使用 `ReadString` 和 `ReadBytes` 方法的时候,我们不需要关心操作系统的类型,直接使用 \n 就可以了。另外,我们也可以使用 `ReadLine()` 方法来实现相同的功能。
|
||||
|
||||
一旦读取到文件末尾,变量 `readerError` 的值将变成非空(事实上,常亮 `io.EOF` 的值是 true),我们就会执行 `return` 语句从而退出循环。
|
||||
一旦读取到文件末尾,变量 `readerError` 的值将变成非空(事实上,常量 `io.EOF` 的值是 true),我们就会执行 `return` 语句从而退出循环。
|
||||
|
||||
**其他类似函数:**
|
||||
|
||||
@@ -234,7 +234,7 @@ func main () {
|
||||
}
|
||||
```
|
||||
|
||||
除了文件句柄,我们还需要 `bufio` 的写入器。我们以只读模式打开文件 `output.dat`,如果文件不存在则自动创建:
|
||||
除了文件句柄,我们还需要 `bufio` 的 `Writer`。我们以只写模式打开文件 `output.dat`,如果文件不存在则自动创建:
|
||||
|
||||
```go
|
||||
outputFile, outputError := os.OpenFile(“output.dat”, os.O_WRONLY|os.O_ CREATE, 0666)
|
||||
@@ -243,6 +243,7 @@ outputFile, outputError := os.OpenFile(“output.dat”, os.O_WRONLY|os.O_ CREAT
|
||||
可以看到,`OpenFile` 函数有三个参数:文件名、一个或多个标志(使用逻辑运算符“|”连接),使用的文件权限。
|
||||
|
||||
我们通常会用到以下标志:
|
||||
|
||||
`os.O_RDONLY`:只读
|
||||
`os.WRONLY`:只写
|
||||
`os.O_CREATE`:创建:如果指定文件不存在,就创建该文件。
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# 文件拷贝
|
||||
如何拷贝一个文件到另一个文件?最简单的方式就是使用io包:
|
||||
如何拷贝一个文件到另一个文件?最简单的方式就是使用 io 包:
|
||||
|
||||
示例 12.10 [filecopy.go](examples/chapter_12/filecopy.go):
|
||||
```go
|
||||
@@ -35,7 +35,8 @@ func CopyFile(dstName, srcName string) (written int64, err error) {
|
||||
|
||||
```
|
||||
|
||||
注意要使用`defer`:当打开目标文件时发生了错误,那么`defer`仍然能够确保`src.Close()`执行。如果不这么做,那么文件会一直保持打开状态并占用资源。
|
||||
注意 `defer` 的使用:当打开目标文件时发生了错误,那么 `defer` 仍然能够确保 `src.Close()`
|
||||
执行。如果不这么做,文件会一直保持打开状态并占用资源。
|
||||
|
||||
## 链接
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# 从命令行读取参数
|
||||
## 12.4.1 os包
|
||||
os包中有一个string类型的切片变量`os.Args`,其用来处理一些基本的命令行参数,它在程序启动后读取命令行输入的参数。来看下面的打招呼程序:
|
||||
## 12.4.1 os 包
|
||||
os 包中有一个 string 类型的切片变量 `os.Args`,用来处理一些基本的命令行参数,它在程序启动后读取命令行输入的参数。来看下面的打招呼程序:
|
||||
|
||||
示例 12.11 [os_args.go](examples/chapter_12/os_args.go):
|
||||
```go
|
||||
@@ -22,21 +22,21 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
我们在IDE或编辑器中直接运行这个程序输出:`Good Morning Alice`
|
||||
我们在 IDE 或编辑器中直接运行这个程序输出:`Good Morning Alice`
|
||||
|
||||
我们在命令行运行`os_args or ./os_args`会得到同样的结果。
|
||||
我们在命令行运行 `os_args or ./os_args` 会得到同样的结果。
|
||||
|
||||
但是我们在命令行加入参数,像这样:`os_args John Bill Marc Luke`,将得到这样的输出:`Good Morning Alice John Bill Marc Luke`
|
||||
|
||||
这个命令行参数会放置在切片`os.Args[]`中(以空格分隔),从索引1开始(`os.Args[0]`放的是程序本身的名字,在本例中是`os_args`)。函数`strings.Join`函数用来连接这些参数,以空格作为间隔。
|
||||
这个命令行参数会放置在切片 `os.Args[]` 中(以空格分隔),从索引1开始(`os.Args[0]` 放的是程序本身的名字,在本例中是 `os_args`)。函数 `strings.Join` 以空格为间隔连接这些参数。
|
||||
|
||||
**练习 12.5**:[hello_who.go](exercises/chapter_12/hello_who.go)
|
||||
写一个"Hello World"的变种程序:把人的名字作为程序命令行执行的一个参数,比如: `hello_who Evan Michael Laura` 那么会输出`Hello Evan Michael Laura`!
|
||||
|
||||
## 12.4.2 flag包
|
||||
flag包有一个扩展功能用来解析命令行选项。但是通常被用来替换基本常量,例如,在某些情况下我们希望在命令行给常量一些不一样的值。(参看19章的项目)
|
||||
## 12.4.2 flag 包
|
||||
flag 包有一个扩展功能用来解析命令行选项。但是通常被用来替换基本常量,例如,在某些情况下我们希望在命令行给常量一些不一样的值。(参看 19 章的项目)
|
||||
|
||||
在flag包中一个Flag被定义成一个含有如下字段的结构体:
|
||||
在 flag 包中一个 Flag 被定义成一个含有如下字段的结构体:
|
||||
|
||||
```go
|
||||
type Flag struct {
|
||||
@@ -47,7 +47,7 @@ type Flag struct {
|
||||
}
|
||||
```
|
||||
|
||||
下面的程序`echo.go`模拟了Unix的echo功能:
|
||||
下面的程序 `echo.go` 模拟了 Unix 的 echo 功能:
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -81,19 +81,20 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
`flat.Parse()`扫描参数列表(或者常量列表)并设置flag, `flag.Arg(i)`表示第i个参数。`Parse()`之后所有`flag.Arg(i)`全部可用,`flag.Arg(0)`就是第一个真实的flag,而不是像`os.Args(o)`放置程序的名字。
|
||||
`flag.Parse()` 扫描参数列表(或者常量列表)并设置 flag, `flag.Arg(i)` 表示第i个参数。`Parse()` 之后 `flag.Arg(i)` 全部可用,`flag.Arg(0)` 就是第一个真实的 flag,而不是像 `os.Args(0)` 放置程序的名字。
|
||||
|
||||
`flag.Narg()`返回参数的数量。解析后flag或常量就可用了。`flag.Bool()`定义了一个默认值是`false`的flag:当在命令行出现了第一个参数(这里是"n"),flag被设置成'true'(NewLine是`*bool`类型)。如果`*NewLine`表示对flag解引用,所以当值是`true`时将添加一个newline。
|
||||
`flag.Narg()` 返回参数的数量。解析后 flag 或常量就可用了。
|
||||
`flag.Bool()` 定义了一个默认值是 `false` 的 flag:当在命令行出现了第一个参数(这里是 "n"),flag 被设置成 `true`(NewLine 是 `*bool` 类型)。flag 被解引用到 `*NewLine`,所以当值是 `true` 时将添加一个 newline("\n")。
|
||||
|
||||
`flag.PrintDefaults()`打印flag的使用帮助信息,本例中打印的是:
|
||||
`flag.PrintDefaults()` 打印 flag 的使用帮助信息,本例中打印的是:
|
||||
|
||||
```go
|
||||
-n=false: print newline
|
||||
-n=false: print newline
|
||||
```
|
||||
|
||||
`flag.VisitAll(fn func(*Flag))`是另一个有用的功能:按照字典顺序遍历flag,并且对每个标签调用fn(参考15.8章的例子)
|
||||
`flag.VisitAll(fn func(*Flag))` 是另一个有用的功能:按照字典顺序遍历 flag,并且对每个标签调用 fn (参考 15.8 章的例子)
|
||||
|
||||
当在命令行(Windows)中执行:`echo.exe A B C`,将输出:`A B C`;执行`echo.exe -n A B C`,将输出:
|
||||
当在命令行(Windows)中执行:`echo.exe A B C`,将输出:`A B C`;执行 `echo.exe -n A B C`,将输出:
|
||||
|
||||
```go
|
||||
A
|
||||
@@ -103,23 +104,23 @@ C
|
||||
|
||||
每个字符的输出都新起一行,每次都在输出的数据前面打印使用帮助信息:`-n=false: print newline`
|
||||
|
||||
对于`flag.Bool`你可以设置布尔型flag来测试你的代码,例如定义一个flag `processedFlag`:
|
||||
对于 `flag.Bool` 你可以设置布尔型 flag 来测试你的代码,例如定义一个 flag `processedFlag`:
|
||||
|
||||
```go
|
||||
var processedFlag = flag.Bool(“proc”, false, “nothing processed yet”)
|
||||
var processedFlag = flag.Bool(“proc”, false, “nothing processed yet”)
|
||||
```
|
||||
|
||||
在后面用如下代码来测试:
|
||||
|
||||
```go
|
||||
if *processedFlag { // found flag -proc
|
||||
r = process()
|
||||
}
|
||||
if *processedFlag { // found flag -proc
|
||||
r = process()
|
||||
}
|
||||
```
|
||||
|
||||
要给flag定义其它类型,可以使用`flag.Int()`,`flag.Float64`,`flag.String()`
|
||||
要给 flag 定义其它类型,可以使用 `flag.Int()`,`flag.Float64`,`flag.String()`
|
||||
|
||||
在15.8章你将找到一个完成的例子。
|
||||
在 15.8 章你将找到一个具体的例子。
|
||||
|
||||
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
# 用buffer读取文件
|
||||
# 用 buffer 读取文件
|
||||
|
||||
在下面的例子中,我们联合使用了缓冲读取文件和命令行flag解析这两项技术。如果不加参数,那么你输入什么屏幕就打印什么。
|
||||
在下面的例子中,我们结合使用了缓冲读取文件和命令行 flag 解析这两项技术。如果不加参数,那么你输入什么屏幕就打印什么。
|
||||
|
||||
参数被认为是文件名,如果文件存在的话就打印文件内容到屏幕。命令行执行`cat test`测试输出。
|
||||
参数被认为是文件名,如果文件存在的话就打印文件内容到屏幕。命令行执行 `cat test` 测试输出。
|
||||
|
||||
示例 12.11 [cat.go](examples/chapter_12/cat.go):
|
||||
|
||||
@@ -44,10 +44,10 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
在12.6章节,我们将看到如何使用缓冲写入。
|
||||
在 12.6 章节,我们将看到如何使用缓冲写入。
|
||||
|
||||
**练习 12.5**:[cat_numbered.go](exercises/chapter_12/cat_numbered.go)
|
||||
扩展cat.go例子,使用flag添加一个选项,目的是为每一行头部加入一个行号。使用`cat -n test`测试输出。
|
||||
扩展 cat.go 例子,使用 flag 添加一个选项,目的是为每一行头部加入一个行号。使用 `cat -n test` 测试输出。
|
||||
|
||||
|
||||
## 链接
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# 用切片读写文件
|
||||
|
||||
切片提供了标准的Go方法来处理I/O缓冲,下面`cat`函数的第二版中,在一个切片缓冲内使用无线for循环(直到文件尾部EOF)读取文件,并写入到标准输出。
|
||||
切片提供了 Go 中处理 I/O 缓冲的标准方式,下面 `cat` 函数的第二版中,在一个切片缓冲内使用无限 for 循环(直到文件尾部 EOF)读取文件,并写入到标准输出(`os.Stdout`)。
|
||||
|
||||
```go
|
||||
func cat(f *os.File) {
|
||||
@@ -22,7 +22,7 @@ func cat(f *os.File) {
|
||||
}
|
||||
|
||||
```
|
||||
代码来自于`cat2.go`,使用了os包中的`os.file`和`Read`方法;`cat2.go`与`cat.go`具有同样的功能。
|
||||
下面的代码来自于 `cat2.go`,使用了 os 包中的 `os.file` 和 `Read` 方法;`cat2.go` 与 `cat.go` 具有同样的功能。
|
||||
|
||||
|
||||
示例 12.14 [cat2.go](examples/chapter_12/cat2.go):
|
||||
@@ -75,5 +75,5 @@ func main() {
|
||||
## 链接
|
||||
|
||||
- [目录](directory.md)
|
||||
- 上一节:[用buffer读取文件](12.5.md)
|
||||
- 下一节:[用defer关闭文件](12.7.md)
|
||||
- 上一节:[用 buffer 读取文件](12.5.md)
|
||||
- 下一节:[用 defer 关闭文件](12.7.md)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# 用defer关闭文件
|
||||
# 用 defer 关闭文件
|
||||
|
||||
`defer`关键字(参看6.4)对于在函数结束时关闭打开的文件非常有用,例如下面的代码片段:
|
||||
`defer` 关键字(参看 6.4)对于在函数结束时关闭打开的文件非常有用,例如下面的代码片段:
|
||||
|
||||
```go
|
||||
func data(name string) string {
|
||||
@@ -11,11 +11,11 @@ func data(name string) string {
|
||||
}
|
||||
|
||||
```
|
||||
在函数return时执行了`f.Close()`
|
||||
在函数 return 后执行了 `f.Close()`
|
||||
|
||||
|
||||
## 链接
|
||||
|
||||
- [目录](directory.md)
|
||||
- 上一节:[用切片读写文件](12.6.md)
|
||||
- 下一节:[一个使用接口的实际例子:fmt.Fprintf](12.8.md)
|
||||
- 下一节:[一个使用接口的实际例子:fmt.Fprintf](12.8.md)
|
||||
|
@@ -109,6 +109,14 @@
|
||||
## 第三部分:Go 高级编程
|
||||
|
||||
- 第12章:[读写数据](12.0.md)
|
||||
- 12.1 [读取用户的输入](12.1.md)
|
||||
- 12.2 [文件读写](12.2.md)
|
||||
- 12.3 [文件拷贝](12.3.md)
|
||||
- 12.4 [从命令行读取参数](12.4.md)
|
||||
- 12.5 [用 buffer 读取文件](12.5.md)
|
||||
- 12.6 [用切片读写文件](12.6.md)
|
||||
- 12.7 [用 defer 关闭文件](12.7.md)
|
||||
- 12.8 [一个使用接口的实际例子:fmt.Fprintf](12.8.md)
|
||||
- 第13章:错误处理与测试
|
||||
- 第14章:goroutine 与 channel
|
||||
- 第15章:网络、模版与网页应用
|
||||
|
Reference in New Issue
Block a user