mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-12 00:11:36 +08:00
12.7-12.12
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
|
||||
## 翻译进度
|
||||
|
||||
12.6 [用切片读写文件](eBook/12.6.md)
|
||||
12.12 [Go 中的密码学](eBook/12.12.md)
|
||||
|
||||
## 支持本书
|
||||
|
||||
|
@@ -30,4 +30,4 @@ Golang 编程:245386165
|
||||
|
||||
|更新日期 |更新内容
|
||||
|----------|------------------
|
||||
|2015-11-13|12.6 用切片读写文件
|
||||
|2015-11-18|12.12 Go 中的密码学
|
||||
|
6
TOC.md
6
TOC.md
@@ -111,3 +111,9 @@
|
||||
- 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)
|
||||
- 12.9 [格式化 JSON 数据](12.9.md)
|
||||
- 12.10 [XML 数据格式](12.10.md)
|
||||
- 12.11 [用 Gob 传输数据](12.11.md)
|
||||
- 12.12 [Go 中的密码学](12.12.md)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
# 12.10 XML 数据格式
|
||||
|
||||
下面是与 12.9 节 JSON 例子等价的 XML 版本:
|
||||
|
||||
```xml
|
||||
<Person>
|
||||
<FirstName>Laura</FirstName>
|
||||
@@ -56,8 +57,11 @@ func main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
/* Output:
|
||||
输出:
|
||||
|
||||
```
|
||||
Token name: Person
|
||||
Token name: FirstName
|
||||
This is the content: Laura
|
||||
@@ -66,9 +70,8 @@ Token name: LastName
|
||||
This is the content: Lynn
|
||||
End of token
|
||||
End of token
|
||||
*/
|
||||
|
||||
```
|
||||
|
||||
包中定义了若干 XML 标签类型:StartElement,Chardata(这是从开始标签到结束标签之间的实际文本),EndElement,Comment,Directive 或 ProcInst。
|
||||
|
||||
包中同样定义了一个结构解析器:`NewParser` 方法持有一个 io.Reader(这里具体类型是 strings.NewReader)并生成一个解析器类型的对象。还有一个 `Token()` 方法返回输入流里的下一个 XML token。在输入流的结尾处,会返回(nil,io.EOF)
|
||||
|
@@ -16,7 +16,6 @@ Gob 文件或流是完全自描述的:里面包含的所有类型都有一个
|
||||
```go
|
||||
type T struct { X, Y, Z int }
|
||||
var t = T{X: 7, Y: 0, Z: 8}
|
||||
|
||||
```
|
||||
|
||||
而在接收者这边可以用一个结构体 U 类型的变量 u 来接收这个值:
|
||||
@@ -24,7 +23,6 @@ var t = T{X: 7, Y: 0, Z: 8}
|
||||
```go
|
||||
type U struct { X, Y *int8 }
|
||||
var u U
|
||||
|
||||
```
|
||||
|
||||
在接收者中,X 的值是7,Y 的值是0(Y的值并没有从 t 中传递过来,因为它是零值)
|
||||
@@ -81,7 +79,6 @@ func main() {
|
||||
fmt.Printf("%q: {%d,%d}\n", q.Name, *q.X, *q.Y)
|
||||
}
|
||||
// Output: "Pythagoras": {3,4}
|
||||
|
||||
```
|
||||
|
||||
示例 12.19 [gob2.go](examples/chapter_12/gob2.go) 编码到文件:
|
||||
@@ -125,14 +122,12 @@ func main() {
|
||||
log.Println("Error in encoding gob")
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
**练习 12.8**:[degob.go](exercises/chapter_12/degob.go):
|
||||
|
||||
写一个程序读取 vcard.gob 文件,解码并打印它的内容。
|
||||
|
||||
|
||||
## 链接
|
||||
|
||||
- [目录](directory.md)
|
||||
|
@@ -37,12 +37,14 @@ func main() {
|
||||
checksum := hasher.Sum(b)
|
||||
fmt.Printf("Result: %x\n", checksum)
|
||||
}
|
||||
/* Output:
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
Result: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
|
||||
Result: [169 74 143 229 204 177 155 166 28 76 8 115 211 145 233 135 152 47 187 211]
|
||||
Result: e2222bfc59850bbb00a722e764a555603bb59b2a
|
||||
*/
|
||||
|
||||
```
|
||||
|
||||
通过调用 `sha1.New()` 创建了一个新的 `hash.Hash` 对象,用来计算 SHA1 校验值。`Hash` 类型实际上是一个接口,它实现了 `io.Writer` 接口:
|
||||
@@ -69,7 +71,6 @@ type Hash interface {
|
||||
// are a multiple of the block size.
|
||||
BlockSize() int
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
通过 io.WriteString 或 hasher.Write 计算给定字符串的校验值。
|
||||
@@ -78,7 +79,6 @@ type Hash interface {
|
||||
|
||||
在示例 12.20 中检验 md5 算法。
|
||||
|
||||
|
||||
## 链接
|
||||
|
||||
- [目录](directory.md)
|
||||
|
@@ -9,10 +9,9 @@ func data(name string) string {
|
||||
contents := io.ReadAll(f)
|
||||
return contents
|
||||
}
|
||||
|
||||
```
|
||||
在函数 return 后执行了 `f.Close()`
|
||||
|
||||
在函数 return 后执行了 `f.Close()`
|
||||
|
||||
## 链接
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
例子程序 `io_interfaces.go` 很好的阐述了 io 包中的接口概念。
|
||||
|
||||
示例 12.15 [io_interfaces.go](examples/chapter_12/io_interfaces.go):
|
||||
|
||||
```go
|
||||
// interfaces being used in the GO-package fmt
|
||||
package main
|
||||
@@ -22,7 +23,6 @@ func main() {
|
||||
fmt.Fprintf(buf, "%s\n", "hello world! - buffered")
|
||||
buf.Flush()
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
输出:
|
||||
@@ -31,6 +31,7 @@ func main() {
|
||||
hello world! - unbuffered
|
||||
hello world! - buffered
|
||||
```
|
||||
|
||||
下面是 `fmt.Fprintf()` 函数的实际签名
|
||||
|
||||
```go
|
||||
@@ -43,7 +44,8 @@ type Writer interface {
|
||||
Write(p []byte) (n int, err error)
|
||||
}
|
||||
```
|
||||
`fmt.Fprintf()` 依据指定的格式向第一个参数内写入字符串,第一参数必须实现了 `io.Writer` 接口。`Fprintf()` 能够写入任何类型,只要其实现了 `Write` 方法,包括 `os.Stdout`,文件(例如 os.File),管道,网络连接,通道等等,同样的也可以使用 bufio 包中缓冲写入。bufio 包中定义了 `type Writer struct{...}`
|
||||
|
||||
`fmt.Fprintf()` 依据指定的格式向第一个参数内写入字符串,第一参数必须实现了 `io.Writer` 接口。`Fprintf()` 能够写入任何类型,只要其实现了 `Write` 方法,包括 `os.Stdout`,文件(例如 os.File),管道,网络连接,通道等等,同样的也可以使用 bufio 包中缓冲写入。bufio 包中定义了 `type Writer struct{...}`。
|
||||
|
||||
bufio.Writer 实现了 Write 方法:
|
||||
|
||||
@@ -56,14 +58,15 @@ func (b *Writer) Write(p []byte) (nn int, err error)
|
||||
```go
|
||||
func NewWriter(wr io.Writer) (b *Writer)
|
||||
```
|
||||
|
||||
其适合任何形式的缓冲写入。
|
||||
|
||||
在缓冲写入的最后千万不要忘了使用 `Flush()`,否则最后的输出不会被写入。
|
||||
|
||||
在 15.2-15.8 章节,我们将使用 `fmt.Fprint` 函数向 `http.ResponseWriter` 写入,其同样实现了 io.Writer 接口。
|
||||
|
||||
|
||||
**练习 12.7**:[remove_3till5char.go](exercises/chapter_12/remove_3till5char.go)
|
||||
|
||||
下面的代码有一个输入文件 `goprogram.go`,然后以每一行为单位读取,从读取的当前行中截取第 3 到第 5 的字节写入另一个文件。然而当你运行这个程序,输出的文件却是个空文件。找出程序逻辑中的 bug,修正它并测试。
|
||||
|
||||
```go
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# 12.9 Json 数据格式
|
||||
# 12.9 JSON 数据格式
|
||||
|
||||
数据结构要在网络中传输或保存到文件,就必须对其编码和解码;目前存在很多编码格式:JSON,XML,gob,Google 缓冲协议等等。Go 语言支持所有这些编码格式;在后面的章节,我们将讨论前三种格式。
|
||||
|
||||
@@ -34,7 +34,6 @@ Go 语言的 json 包可以让你在程序中方便的读取和写入 JSON 数
|
||||
|
||||
我们将在下面的例子里使用 json 包,并使用练习 10.1 vcard.go 中一个简化版本的 Address 和 VCard 结构(为了简单起见,我们忽略了很多错误处理,不过在实际应用中你必须要合理的处理这些错误,参阅 13 章)
|
||||
|
||||
|
||||
示例 12.16 [json.go](examples/chapter_12/json.go):
|
||||
|
||||
```go
|
||||
@@ -78,7 +77,6 @@ func main() {
|
||||
log.Println("Error in encoding json")
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
`json.Marshal()` 的函数签名是 `func Marshal(v interface{}) ([]byte, error)`,下面是数据编码后的 JSON 文本(实际上是一个 []bytes):
|
||||
@@ -185,7 +183,7 @@ for k, v := range m {
|
||||
|
||||
通过这种方式,你可以处理未知的 JSON 数据,同时可以确保类型安全。
|
||||
|
||||
### 解码数据到结构:
|
||||
### 解码数据到结构
|
||||
|
||||
如果我们事先知道 JSON 数据,我们可以定义一个适当的结构并对 JSON 数据反序列化。下面的例子中,我们将定义:
|
||||
|
||||
@@ -208,6 +206,7 @@ err := json.Unmarshal(b, &m)
|
||||
程序实际上是分配了一个新的切片。这是一个典型的反序列化引用类型(指针、切片和 map)的例子。
|
||||
|
||||
### 编码和解码流
|
||||
|
||||
json 包提供 Decoder 和 Encoder 类型来支持常用 JSON 数据流读写。NewDecoder 和 NewEncoder 函数分别封装了 io.Reader 和 io.Writer 接口。
|
||||
|
||||
```go
|
||||
|
@@ -120,7 +120,7 @@
|
||||
- 12.6 [用切片读写文件](12.6.md)
|
||||
- 12.7 [用 defer 关闭文件](12.7.md)
|
||||
- 12.8 [使用接口的实际例子:fmt.Fprintf](12.8.md)
|
||||
- 12.9 [格式化 Json 数据](12.9.md)
|
||||
- 12.9 [格式化 JSON 数据](12.9.md)
|
||||
- 12.10 [XML 数据格式](12.10.md)
|
||||
- 12.11 [用 Gob 传输数据](12.11.md)
|
||||
- 12.12 [Go 中的密码学](12.12.md)
|
||||
|
Reference in New Issue
Block a user