第7章,部分字词修订,语序调整。少量错误修订。

This commit is contained in:
zhliner
2017-08-24 22:29:24 +08:00
parent 9a9b9a0594
commit 17919273e1
14 changed files with 87 additions and 87 deletions

View File

@@ -15,7 +15,7 @@ func ListenAndServe(address string, h Handler) error
ListenAndServe函数需要一个例如“localhost:8000”的服务器地址和一个所有请求都可以分派的Handler接口实例。它会一直运行直到这个服务因为一个错误而失败或者启动失败它的返回值一定是一个非空的错误。
想象一个电子商务网站,为了销售它的数据库将它物品的价格映射成美元。下面这个程序可能是能想到的最简单的实现了。它将库存清单模型化为一个命名为database的map类型我们给这个类型一个ServeHttp方法这样它可以满足http.Handler接口。这个handler会遍历整个map并输出物品信息。
想象一个电子商务网站,为了销售,将数据库物品的价格映射成美元。下面这个程序可能是能想到的最简单的实现了。它将库存清单模型化为一个命名为database的map类型我们给这个类型一个ServeHttp方法这样它可以满足http.Handler接口。这个handler会遍历整个map并输出物品信息。
<u><i>gopl.io/ch7/http1</i></u>
```go
@@ -53,7 +53,7 @@ shoes: $50.00
socks: $5.00
```
目前为止这个服务器不考虑URL只能为每个请求列出它全部的库存清单。更真实的服务器会定义多个不同的URL每一个都会触发一个不同的行为。让我们使用/list来调用已经存在的这个行为并且增加另一个/price调用表明单个货品的价格像这样/price?item=socks来指定一个请求参数。
目前为止这个服务器不考虑URL只能为每个请求列出它全部的库存清单。更真实的服务器会定义多个不同的URL每一个都会触发一个不同的行为。让我们使用/list来调用已经存在的这个行为并且增加另一个/price调用表明单个货品的价格像这样/price?item=socks来指定一个请求参数。
<u><i>gopl.io/ch7/http2</i></u>
```go
@@ -112,7 +112,7 @@ no such page: /help
对于更复杂的应用一些ServeMux可以通过组合来处理更加错综复杂的路由需求。Go语言目前没有一个权威的web框架就像Ruby语言有Rails和python有Django。这并不是说这样的框架不存在而是Go语言标准库中的构建模块就已经非常灵活以至于这些框架都是不必要的。此外尽管在一个项目早期使用框架是非常方便的但是它们带来额外的复杂度会使长期的维护更加困难。
在下面的程序中我们创建一个ServeMux并且使用它将URL和相应处理/list和/price操作的handler联系起来这些操作逻辑都已经被分到不同的方法中。然后我门在调用ListenAndServe函数中使用ServeMux为主要的handler。
在下面的程序中我们创建一个ServeMux并且使用它将URL和相应处理/list和/price操作的handler联系起来这些操作逻辑都已经被分到不同的方法中。然后我门在调用ListenAndServe函数中使用ServeMux为主要的handler。
<u><i>gopl.io/ch7/http3</i></u>
```go
@@ -144,13 +144,13 @@ func (db database) price(w http.ResponseWriter, req *http.Request) {
}
```
让我们关注这两个注册到handlers上的调用。第一个db.list是一个方法值 (§6.4),它是下面这个类型的值
让我们关注这两个注册到handlers上的调用。第一个db.list是一个方法值 (§6.4),它是下面这个类型的值
```go
func(w http.ResponseWriter, req *http.Request)
```
也就是说db.list的调用会援引一个接收者是db的database.list方法。所以db.list是一个实现了handler类似行为的函数但是因为它没有方法所以它不满足http.Handler接口并且不能直接传给mux.Handle。
也就是说db.list的调用会援引一个接收者是db的database.list方法。所以db.list是一个实现了handler类似行为的函数但是因为它没有方法(理解:该方法没有它自己的方法)所以它不满足http.Handler接口并且不能直接传给mux.Handle。
语句http.HandlerFunc(db.list)是一个转换而非一个函数调用因为http.HandlerFunc是一个类型。它有如下的定义
@@ -165,7 +165,7 @@ func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
}
```
HandlerFunc显示了在Go语言接口机制中一些不同寻常的特点。这是一个实现了接口http.Handler方法的函数类型。ServeHTTP方法的行为调用了它本身的函数。因此HandlerFunc是一个让函数值满足一个接口的适配器这里函数和这个接口仅有的方法有相同的函数签名。实际上这个技巧让一个单一的类型例如database以多种方式满足http.Handler接口一种通过它的list方法一种通过它的price方法等等。
HandlerFunc显示了在Go语言接口机制中一些不同寻常的特点。这是一个实现了接口http.Handler方法的函数类型。ServeHTTP方法的行为调用了它的函数本身。因此HandlerFunc是一个让函数值满足一个接口的适配器这里函数和这个接口仅有的方法有相同的函数签名。实际上这个技巧让一个单一的类型例如database以多种方式满足http.Handler接口一种通过它的list方法一种通过它的price方法等等。
因为handler通过这种方式注册非常普遍ServeMux有一个方便的HandleFunc方法它帮我们简化handler注册代码成这样
@@ -175,7 +175,7 @@ mux.HandleFunc("/list", db.list)
mux.HandleFunc("/price", db.price)
```
从上面的代码很容易看出应该怎么构建一个程序,它有两个不同的web服务器监听不同的端口并且定义不同的URL将它们指派到不同的handler。我们只要构建另外一个ServeMux并且调用一次ListenAndServe可能并行的。但是在大多数程序中一个web服务器就足够了。此外在一个应用程序的多个文件中定义HTTP handler也是非常典型的如果它们必须全部都显示的注册到这个应用的ServeMux实例上会比较麻烦。
从上面的代码很容易看出应该怎么构建一个程序:由两个不同的web服务器监听不同的端口并且定义不同的URL将它们指派到不同的handler。我们只要构建另外一个ServeMux并且调用一次ListenAndServe可能并行的。但是在大多数程序中一个web服务器就足够了。此外在一个应用程序的多个文件中定义HTTP handler也是非常典型的如果它们必须全部都显式地注册到这个应用的ServeMux实例上会比较麻烦。
所以为了方便net/http包提供了一个全局的ServeMux实例DefaultServerMux和包级别的http.Handle和http.HandleFunc函数。现在为了使用DefaultServeMux作为服务器的主handler我们不需要将它传给ListenAndServe函数nil值就可以工作。
@@ -191,8 +191,8 @@ func main() {
}
```
最后一个重要的提示就像我们在1.7节中提到的web服务器在一个新的协程中调用每一个handler所以当handler获取其它协程或者这个handler本身的其它请求也可以访问变量时一定要使用预防措施比如锁机制。我们后面的两章中讲到并发相关的知识。
最后一个重要的提示就像我们在1.7节中提到的web服务器在一个新的协程中调用每一个handler所以当handler获取其它协程或者这个handler本身的其它请求也可以访问变量时一定要使用预防措施比如锁机制。我们后面的两章中讲到并发相关的知识。
**练习 7.11** 增加额外的handler让客端可以创建,读取,更新和删除数据库记录。例如,一个形如 `/update?item=socks&price=6` 的请求会更新库存清单里一个货品的价格并且当这个货品不存在或价格无效时返回一个错误值。(注意:这个修改会引入变量同时更新的问题)
**练习 7.11** 增加额外的handler让客端可以创建,读取,更新和删除数据库记录。例如,一个形如 `/update?item=socks&price=6` 的请求会更新库存清单里一个货品的价格并且当这个货品不存在或价格无效时返回一个错误值。(注意:这个修改会引入变量同时更新的问题)
**练习 7.12** 修改/list的handler让它把输出打印成一个HTML的表格而不是文本。html/template包(§4.6)可能会对你有帮助。