2015-12-09 07:57:17 +00:00
<!DOCTYPE HTML>
< html lang = "zh-tw" >
< head >
< meta charset = "UTF-8" >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" / >
< title > Web服務 | Go编程语言< / title >
< meta content = "text/html; charset=utf-8" http-equiv = "Content-Type" >
< meta name = "description" content = "" >
< meta name = "generator" content = "GitBook 2.5.2" >
< meta name = "HandheldFriendly" content = "true" / >
< meta name = "viewport" content = "width=device-width, initial-scale=1, user-scalable=no" >
< meta name = "apple-mobile-web-app-capable" content = "yes" >
< meta name = "apple-mobile-web-app-status-bar-style" content = "black" >
< link rel = "apple-touch-icon-precomposed" sizes = "152x152" href = "../gitbook/images/apple-touch-icon-precomposed-152.png" >
< link rel = "shortcut icon" href = "../gitbook/images/favicon.ico" type = "image/x-icon" >
< link rel = "stylesheet" href = "../gitbook/style.css" >
< link rel = "stylesheet" href = "../gitbook/plugins/gitbook-plugin-highlight/website.css" >
< link rel = "stylesheet" href = "../gitbook/plugins/gitbook-plugin-search/search.css" >
< link rel = "stylesheet" href = "../gitbook/plugins/gitbook-plugin-fontsettings/website.css" >
< link rel = "next" href = "../ch1/ch1-08.html" / >
< link rel = "prev" href = "../ch1/ch1-06.html" / >
< / head >
< body >
2015-12-24 06:47:06 +00:00
< div class = "book" data-level = "1.7" data-chapter-title = "Web服務" data-filepath = "ch1/ch1-07.md" data-basepath = ".." data-revision = "Thu Dec 24 2015 14:42:02 GMT+0800 (中国标准时间)" >
2015-12-09 07:57:17 +00:00
< div class = "book-summary" >
< nav role = "navigation" >
< ul class = "summary" >
< li class = "chapter " data-level = "0" data-path = "index.html" >
< a href = "../index.html" >
< i class = "fa fa-check" > < / i >
前言
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "0.1" data-path = "ch0/ch0-01.html" >
< a href = "../ch0/ch0-01.html" >
< i class = "fa fa-check" > < / i >
< b > 0.1.< / b >
Go語言起源
< / a >
< / li >
< li class = "chapter " data-level = "0.2" data-path = "ch0/ch0-02.html" >
< a href = "../ch0/ch0-02.html" >
< i class = "fa fa-check" > < / i >
< b > 0.2.< / b >
Go語言項目
< / a >
< / li >
< li class = "chapter " data-level = "0.3" data-path = "ch0/ch0-03.html" >
< a href = "../ch0/ch0-03.html" >
< i class = "fa fa-check" > < / i >
< b > 0.3.< / b >
本書的組織
< / a >
< / li >
< li class = "chapter " data-level = "0.4" data-path = "ch0/ch0-04.html" >
< a href = "../ch0/ch0-04.html" >
< i class = "fa fa-check" > < / i >
< b > 0.4.< / b >
更多的信息
< / a >
< / li >
< li class = "chapter " data-level = "0.5" data-path = "ch0/ch0-05.html" >
< a href = "../ch0/ch0-05.html" >
< i class = "fa fa-check" > < / i >
< b > 0.5.< / b >
2015-12-21 04:55:18 +00:00
致謝
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "1" data-path = "ch1/ch1.html" >
< a href = "../ch1/ch1.html" >
< i class = "fa fa-check" > < / i >
< b > 1.< / b >
入門
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "1.1" data-path = "ch1/ch1-01.html" >
< a href = "../ch1/ch1-01.html" >
< i class = "fa fa-check" > < / i >
< b > 1.1.< / b >
Hello, World
< / a >
< / li >
< li class = "chapter " data-level = "1.2" data-path = "ch1/ch1-02.html" >
< a href = "../ch1/ch1-02.html" >
< i class = "fa fa-check" > < / i >
< b > 1.2.< / b >
命令行參數
< / a >
< / li >
< li class = "chapter " data-level = "1.3" data-path = "ch1/ch1-03.html" >
< a href = "../ch1/ch1-03.html" >
< i class = "fa fa-check" > < / i >
< b > 1.3.< / b >
2015-12-21 04:55:18 +00:00
査找重複的行
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "1.4" data-path = "ch1/ch1-04.html" >
< a href = "../ch1/ch1-04.html" >
< i class = "fa fa-check" > < / i >
< b > 1.4.< / b >
2015-12-21 04:55:18 +00:00
GIF動畵
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "1.5" data-path = "ch1/ch1-05.html" >
< a href = "../ch1/ch1-05.html" >
< i class = "fa fa-check" > < / i >
< b > 1.5.< / b >
穫取URL
< / a >
< / li >
< li class = "chapter " data-level = "1.6" data-path = "ch1/ch1-06.html" >
< a href = "../ch1/ch1-06.html" >
< i class = "fa fa-check" > < / i >
< b > 1.6.< / b >
2015-12-21 04:55:18 +00:00
併發穫取多個URL
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter active" data-level = "1.7" data-path = "ch1/ch1-07.html" >
< a href = "../ch1/ch1-07.html" >
< i class = "fa fa-check" > < / i >
< b > 1.7.< / b >
Web服務
< / a >
< / li >
< li class = "chapter " data-level = "1.8" data-path = "ch1/ch1-08.html" >
< a href = "../ch1/ch1-08.html" >
< i class = "fa fa-check" > < / i >
< b > 1.8.< / b >
本章要點
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "2" data-path = "ch2/ch2.html" >
< a href = "../ch2/ch2.html" >
< i class = "fa fa-check" > < / i >
< b > 2.< / b >
程序結構
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "2.1" data-path = "ch2/ch2-01.html" >
< a href = "../ch2/ch2-01.html" >
< i class = "fa fa-check" > < / i >
< b > 2.1.< / b >
命名
< / a >
< / li >
< li class = "chapter " data-level = "2.2" data-path = "ch2/ch2-02.html" >
< a href = "../ch2/ch2-02.html" >
< i class = "fa fa-check" > < / i >
< b > 2.2.< / b >
聲明
< / a >
< / li >
< li class = "chapter " data-level = "2.3" data-path = "ch2/ch2-03.html" >
< a href = "../ch2/ch2-03.html" >
< i class = "fa fa-check" > < / i >
< b > 2.3.< / b >
變量
< / a >
< / li >
< li class = "chapter " data-level = "2.4" data-path = "ch2/ch2-04.html" >
< a href = "../ch2/ch2-04.html" >
< i class = "fa fa-check" > < / i >
< b > 2.4.< / b >
賦值
< / a >
< / li >
< li class = "chapter " data-level = "2.5" data-path = "ch2/ch2-05.html" >
< a href = "../ch2/ch2-05.html" >
< i class = "fa fa-check" > < / i >
< b > 2.5.< / b >
類型
< / a >
< / li >
< li class = "chapter " data-level = "2.6" data-path = "ch2/ch2-06.html" >
< a href = "../ch2/ch2-06.html" >
< i class = "fa fa-check" > < / i >
< b > 2.6.< / b >
包和文件
< / a >
< / li >
< li class = "chapter " data-level = "2.7" data-path = "ch2/ch2-07.html" >
< a href = "../ch2/ch2-07.html" >
< i class = "fa fa-check" > < / i >
< b > 2.7.< / b >
作用域
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "3" data-path = "ch3/ch3.html" >
< a href = "../ch3/ch3.html" >
< i class = "fa fa-check" > < / i >
< b > 3.< / b >
基礎數據類型
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "3.1" data-path = "ch3/ch3-01.html" >
< a href = "../ch3/ch3-01.html" >
< i class = "fa fa-check" > < / i >
< b > 3.1.< / b >
整型
< / a >
< / li >
< li class = "chapter " data-level = "3.2" data-path = "ch3/ch3-02.html" >
< a href = "../ch3/ch3-02.html" >
< i class = "fa fa-check" > < / i >
< b > 3.2.< / b >
浮點數
< / a >
< / li >
< li class = "chapter " data-level = "3.3" data-path = "ch3/ch3-03.html" >
< a href = "../ch3/ch3-03.html" >
< i class = "fa fa-check" > < / i >
< b > 3.3.< / b >
2015-12-21 04:55:18 +00:00
複數
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "3.4" data-path = "ch3/ch3-04.html" >
< a href = "../ch3/ch3-04.html" >
< i class = "fa fa-check" > < / i >
< b > 3.4.< / b >
2015-12-21 04:55:18 +00:00
布爾型
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "3.5" data-path = "ch3/ch3-05.html" >
< a href = "../ch3/ch3-05.html" >
< i class = "fa fa-check" > < / i >
< b > 3.5.< / b >
字符串
< / a >
< / li >
< li class = "chapter " data-level = "3.6" data-path = "ch3/ch3-06.html" >
< a href = "../ch3/ch3-06.html" >
< i class = "fa fa-check" > < / i >
< b > 3.6.< / b >
常量
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "4" data-path = "ch4/ch4.html" >
< a href = "../ch4/ch4.html" >
< i class = "fa fa-check" > < / i >
< b > 4.< / b >
2015-12-21 04:55:18 +00:00
複合數據類型
2015-12-09 07:57:17 +00:00
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "4.1" data-path = "ch4/ch4-01.html" >
< a href = "../ch4/ch4-01.html" >
< i class = "fa fa-check" > < / i >
< b > 4.1.< / b >
數組
< / a >
< / li >
< li class = "chapter " data-level = "4.2" data-path = "ch4/ch4-02.html" >
< a href = "../ch4/ch4-02.html" >
< i class = "fa fa-check" > < / i >
< b > 4.2.< / b >
切片
< / a >
< / li >
< li class = "chapter " data-level = "4.3" data-path = "ch4/ch4-03.html" >
< a href = "../ch4/ch4-03.html" >
< i class = "fa fa-check" > < / i >
< b > 4.3.< / b >
字典
< / a >
< / li >
< li class = "chapter " data-level = "4.4" data-path = "ch4/ch4-04.html" >
< a href = "../ch4/ch4-04.html" >
< i class = "fa fa-check" > < / i >
< b > 4.4.< / b >
結構體
< / a >
< / li >
< li class = "chapter " data-level = "4.5" data-path = "ch4/ch4-05.html" >
< a href = "../ch4/ch4-05.html" >
< i class = "fa fa-check" > < / i >
< b > 4.5.< / b >
JSON
< / a >
< / li >
< li class = "chapter " data-level = "4.6" data-path = "ch4/ch4-06.html" >
< a href = "../ch4/ch4-06.html" >
< i class = "fa fa-check" > < / i >
< b > 4.6.< / b >
文本和HTML模闆
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "5" data-path = "ch5/ch5.html" >
< a href = "../ch5/ch5.html" >
< i class = "fa fa-check" > < / i >
< b > 5.< / b >
函數
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "5.1" data-path = "ch5/ch5-01.html" >
< a href = "../ch5/ch5-01.html" >
< i class = "fa fa-check" > < / i >
< b > 5.1.< / b >
函數聲明
< / a >
< / li >
< li class = "chapter " data-level = "5.2" data-path = "ch5/ch5-02.html" >
< a href = "../ch5/ch5-02.html" >
< i class = "fa fa-check" > < / i >
< b > 5.2.< / b >
遞歸
< / a >
< / li >
< li class = "chapter " data-level = "5.3" data-path = "ch5/ch5-03.html" >
< a href = "../ch5/ch5-03.html" >
< i class = "fa fa-check" > < / i >
< b > 5.3.< / b >
多返迴值
< / a >
< / li >
< li class = "chapter " data-level = "5.4" data-path = "ch5/ch5-04.html" >
< a href = "../ch5/ch5-04.html" >
< i class = "fa fa-check" > < / i >
< b > 5.4.< / b >
錯誤
< / a >
< / li >
< li class = "chapter " data-level = "5.5" data-path = "ch5/ch5-05.html" >
< a href = "../ch5/ch5-05.html" >
< i class = "fa fa-check" > < / i >
< b > 5.5.< / b >
函數值
< / a >
< / li >
< li class = "chapter " data-level = "5.6" data-path = "ch5/ch5-06.html" >
< a href = "../ch5/ch5-06.html" >
< i class = "fa fa-check" > < / i >
< b > 5.6.< / b >
匿名函數
< / a >
< / li >
< li class = "chapter " data-level = "5.7" data-path = "ch5/ch5-07.html" >
< a href = "../ch5/ch5-07.html" >
< i class = "fa fa-check" > < / i >
< b > 5.7.< / b >
可變參數
< / a >
< / li >
< li class = "chapter " data-level = "5.8" data-path = "ch5/ch5-08.html" >
< a href = "../ch5/ch5-08.html" >
< i class = "fa fa-check" > < / i >
< b > 5.8.< / b >
Deferred函數
< / a >
< / li >
< li class = "chapter " data-level = "5.9" data-path = "ch5/ch5-09.html" >
< a href = "../ch5/ch5-09.html" >
< i class = "fa fa-check" > < / i >
< b > 5.9.< / b >
Panic異常
< / a >
< / li >
< li class = "chapter " data-level = "5.10" data-path = "ch5/ch5-10.html" >
< a href = "../ch5/ch5-10.html" >
< i class = "fa fa-check" > < / i >
< b > 5.10.< / b >
Recover捕穫異常
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "6" data-path = "ch6/ch6.html" >
< a href = "../ch6/ch6.html" >
< i class = "fa fa-check" > < / i >
< b > 6.< / b >
方法
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "6.1" data-path = "ch6/ch6-01.html" >
< a href = "../ch6/ch6-01.html" >
< i class = "fa fa-check" > < / i >
< b > 6.1.< / b >
方法聲明
< / a >
< / li >
< li class = "chapter " data-level = "6.2" data-path = "ch6/ch6-02.html" >
< a href = "../ch6/ch6-02.html" >
< i class = "fa fa-check" > < / i >
< b > 6.2.< / b >
2015-12-21 04:55:18 +00:00
基於指針對象的方法
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "6.3" data-path = "ch6/ch6-03.html" >
< a href = "../ch6/ch6-03.html" >
< i class = "fa fa-check" > < / i >
< b > 6.3.< / b >
通過嵌入結構體來擴展類型
< / a >
< / li >
< li class = "chapter " data-level = "6.4" data-path = "ch6/ch6-04.html" >
< a href = "../ch6/ch6-04.html" >
< i class = "fa fa-check" > < / i >
< b > 6.4.< / b >
2015-12-21 04:55:18 +00:00
方法值和方法表達式
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "6.5" data-path = "ch6/ch6-05.html" >
< a href = "../ch6/ch6-05.html" >
< i class = "fa fa-check" > < / i >
< b > 6.5.< / b >
示例: Bit數組
< / a >
< / li >
< li class = "chapter " data-level = "6.6" data-path = "ch6/ch6-06.html" >
< a href = "../ch6/ch6-06.html" >
< i class = "fa fa-check" > < / i >
< b > 6.6.< / b >
封裝
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "7" data-path = "ch7/ch7.html" >
< a href = "../ch7/ch7.html" >
< i class = "fa fa-check" > < / i >
< b > 7.< / b >
接口
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "7.1" data-path = "ch7/ch7-01.html" >
< a href = "../ch7/ch7-01.html" >
< i class = "fa fa-check" > < / i >
< b > 7.1.< / b >
2015-12-21 04:55:18 +00:00
接口是合約
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "7.2" data-path = "ch7/ch7-02.html" >
< a href = "../ch7/ch7-02.html" >
< i class = "fa fa-check" > < / i >
< b > 7.2.< / b >
接口類型
< / a >
< / li >
< li class = "chapter " data-level = "7.3" data-path = "ch7/ch7-03.html" >
< a href = "../ch7/ch7-03.html" >
< i class = "fa fa-check" > < / i >
< b > 7.3.< / b >
實現接口的條件
< / a >
< / li >
< li class = "chapter " data-level = "7.4" data-path = "ch7/ch7-04.html" >
< a href = "../ch7/ch7-04.html" >
< i class = "fa fa-check" > < / i >
< b > 7.4.< / b >
flag.Value接口
< / a >
< / li >
< li class = "chapter " data-level = "7.5" data-path = "ch7/ch7-05.html" >
< a href = "../ch7/ch7-05.html" >
< i class = "fa fa-check" > < / i >
< b > 7.5.< / b >
接口值
< / a >
< / li >
< li class = "chapter " data-level = "7.6" data-path = "ch7/ch7-06.html" >
< a href = "../ch7/ch7-06.html" >
< i class = "fa fa-check" > < / i >
< b > 7.6.< / b >
sort.Interface接口
< / a >
< / li >
< li class = "chapter " data-level = "7.7" data-path = "ch7/ch7-07.html" >
< a href = "../ch7/ch7-07.html" >
< i class = "fa fa-check" > < / i >
< b > 7.7.< / b >
http.Handler接口
< / a >
< / li >
< li class = "chapter " data-level = "7.8" data-path = "ch7/ch7-08.html" >
< a href = "../ch7/ch7-08.html" >
< i class = "fa fa-check" > < / i >
< b > 7.8.< / b >
error接口
< / a >
< / li >
< li class = "chapter " data-level = "7.9" data-path = "ch7/ch7-09.html" >
< a href = "../ch7/ch7-09.html" >
< i class = "fa fa-check" > < / i >
< b > 7.9.< / b >
2015-12-21 04:55:18 +00:00
示例: 表達式求值
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "7.10" data-path = "ch7/ch7-10.html" >
< a href = "../ch7/ch7-10.html" >
< i class = "fa fa-check" > < / i >
< b > 7.10.< / b >
類型斷言
< / a >
< / li >
< li class = "chapter " data-level = "7.11" data-path = "ch7/ch7-11.html" >
< a href = "../ch7/ch7-11.html" >
< i class = "fa fa-check" > < / i >
< b > 7.11.< / b >
2015-12-21 04:55:18 +00:00
基於類型斷言識别錯誤類型
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "7.12" data-path = "ch7/ch7-12.html" >
< a href = "../ch7/ch7-12.html" >
< i class = "fa fa-check" > < / i >
< b > 7.12.< / b >
通過類型斷言査詢接口
< / a >
< / li >
< li class = "chapter " data-level = "7.13" data-path = "ch7/ch7-13.html" >
< a href = "../ch7/ch7-13.html" >
< i class = "fa fa-check" > < / i >
< b > 7.13.< / b >
類型分支
< / a >
< / li >
< li class = "chapter " data-level = "7.14" data-path = "ch7/ch7-14.html" >
< a href = "../ch7/ch7-14.html" >
< i class = "fa fa-check" > < / i >
< b > 7.14.< / b >
示例: 基於標記的XML解碼
< / a >
< / li >
< li class = "chapter " data-level = "7.15" data-path = "ch7/ch7-15.html" >
< a href = "../ch7/ch7-15.html" >
< i class = "fa fa-check" > < / i >
< b > 7.15.< / b >
補充幾點
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "8" data-path = "ch8/ch8.html" >
< a href = "../ch8/ch8.html" >
< i class = "fa fa-check" > < / i >
< b > 8.< / b >
Goroutines和Channels
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "8.1" data-path = "ch8/ch8-01.html" >
< a href = "../ch8/ch8-01.html" >
< i class = "fa fa-check" > < / i >
< b > 8.1.< / b >
Goroutines
< / a >
< / li >
< li class = "chapter " data-level = "8.2" data-path = "ch8/ch8-02.html" >
< a href = "../ch8/ch8-02.html" >
< i class = "fa fa-check" > < / i >
< b > 8.2.< / b >
2015-12-21 04:55:18 +00:00
示例: 併發的Clock服務
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "8.3" data-path = "ch8/ch8-03.html" >
< a href = "../ch8/ch8-03.html" >
< i class = "fa fa-check" > < / i >
< b > 8.3.< / b >
2015-12-21 04:55:18 +00:00
示例: 併發的Echo服務
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "8.4" data-path = "ch8/ch8-04.html" >
< a href = "../ch8/ch8-04.html" >
< i class = "fa fa-check" > < / i >
< b > 8.4.< / b >
Channels
< / a >
< / li >
< li class = "chapter " data-level = "8.5" data-path = "ch8/ch8-05.html" >
< a href = "../ch8/ch8-05.html" >
< i class = "fa fa-check" > < / i >
< b > 8.5.< / b >
併行的循環
< / a >
< / li >
< li class = "chapter " data-level = "8.6" data-path = "ch8/ch8-06.html" >
< a href = "../ch8/ch8-06.html" >
< i class = "fa fa-check" > < / i >
< b > 8.6.< / b >
2015-12-21 04:55:18 +00:00
示例: 併發的Web爬蟲
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "8.7" data-path = "ch8/ch8-07.html" >
< a href = "../ch8/ch8-07.html" >
< i class = "fa fa-check" > < / i >
< b > 8.7.< / b >
2015-12-21 04:55:18 +00:00
基於select的多路複用
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "8.8" data-path = "ch8/ch8-08.html" >
< a href = "../ch8/ch8-08.html" >
< i class = "fa fa-check" > < / i >
< b > 8.8.< / b >
2015-12-21 04:55:18 +00:00
示例: 併發的字典遍歷
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "8.9" data-path = "ch8/ch8-09.html" >
< a href = "../ch8/ch8-09.html" >
< i class = "fa fa-check" > < / i >
< b > 8.9.< / b >
2015-12-21 04:55:18 +00:00
併發的退齣
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "8.10" data-path = "ch8/ch8-10.html" >
< a href = "../ch8/ch8-10.html" >
< i class = "fa fa-check" > < / i >
< b > 8.10.< / b >
示例: 聊天服務
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "9" data-path = "ch9/ch9.html" >
< a href = "../ch9/ch9.html" >
< i class = "fa fa-check" > < / i >
< b > 9.< / b >
2015-12-21 04:55:18 +00:00
基於共享變量的併發
2015-12-09 07:57:17 +00:00
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "9.1" data-path = "ch9/ch9-01.html" >
< a href = "../ch9/ch9-01.html" >
< i class = "fa fa-check" > < / i >
< b > 9.1.< / b >
競爭條件
< / a >
< / li >
< li class = "chapter " data-level = "9.2" data-path = "ch9/ch9-02.html" >
< a href = "../ch9/ch9-02.html" >
< i class = "fa fa-check" > < / i >
< b > 9.2.< / b >
sync.Mutex互斥鎖
< / a >
< / li >
< li class = "chapter " data-level = "9.3" data-path = "ch9/ch9-03.html" >
< a href = "../ch9/ch9-03.html" >
< i class = "fa fa-check" > < / i >
< b > 9.3.< / b >
sync.RWMutex讀寫鎖
< / a >
< / li >
< li class = "chapter " data-level = "9.4" data-path = "ch9/ch9-04.html" >
< a href = "../ch9/ch9-04.html" >
< i class = "fa fa-check" > < / i >
< b > 9.4.< / b >
2015-12-21 04:55:18 +00:00
內存同步
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "9.5" data-path = "ch9/ch9-05.html" >
< a href = "../ch9/ch9-05.html" >
< i class = "fa fa-check" > < / i >
< b > 9.5.< / b >
sync.Once初始化
< / a >
< / li >
< li class = "chapter " data-level = "9.6" data-path = "ch9/ch9-06.html" >
< a href = "../ch9/ch9-06.html" >
< i class = "fa fa-check" > < / i >
< b > 9.6.< / b >
競爭條件檢測
< / a >
< / li >
< li class = "chapter " data-level = "9.7" data-path = "ch9/ch9-07.html" >
< a href = "../ch9/ch9-07.html" >
< i class = "fa fa-check" > < / i >
< b > 9.7.< / b >
2015-12-21 04:55:18 +00:00
示例: 併發的非阻塞緩存
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "9.8" data-path = "ch9/ch9-08.html" >
< a href = "../ch9/ch9-08.html" >
< i class = "fa fa-check" > < / i >
< b > 9.8.< / b >
2015-12-21 04:55:18 +00:00
Goroutines和線程
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "10" data-path = "ch10/ch10.html" >
< a href = "../ch10/ch10.html" >
< i class = "fa fa-check" > < / i >
< b > 10.< / b >
包和工具
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "10.1" data-path = "ch10/ch10-01.html" >
< a href = "../ch10/ch10-01.html" >
< i class = "fa fa-check" > < / i >
< b > 10.1.< / b >
簡介
< / a >
< / li >
< li class = "chapter " data-level = "10.2" data-path = "ch10/ch10-02.html" >
< a href = "../ch10/ch10-02.html" >
< i class = "fa fa-check" > < / i >
< b > 10.2.< / b >
導入路徑
< / a >
< / li >
< li class = "chapter " data-level = "10.3" data-path = "ch10/ch10-03.html" >
< a href = "../ch10/ch10-03.html" >
< i class = "fa fa-check" > < / i >
< b > 10.3.< / b >
包聲明
< / a >
< / li >
< li class = "chapter " data-level = "10.4" data-path = "ch10/ch10-04.html" >
< a href = "../ch10/ch10-04.html" >
< i class = "fa fa-check" > < / i >
< b > 10.4.< / b >
導入聲明
< / a >
< / li >
< li class = "chapter " data-level = "10.5" data-path = "ch10/ch10-05.html" >
< a href = "../ch10/ch10-05.html" >
< i class = "fa fa-check" > < / i >
< b > 10.5.< / b >
匿名導入
< / a >
< / li >
< li class = "chapter " data-level = "10.6" data-path = "ch10/ch10-06.html" >
< a href = "../ch10/ch10-06.html" >
< i class = "fa fa-check" > < / i >
< b > 10.6.< / b >
包和命名
< / a >
< / li >
< li class = "chapter " data-level = "10.7" data-path = "ch10/ch10-07.html" >
< a href = "../ch10/ch10-07.html" >
< i class = "fa fa-check" > < / i >
< b > 10.7.< / b >
工具
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "11" data-path = "ch11/ch11.html" >
< a href = "../ch11/ch11.html" >
< i class = "fa fa-check" > < / i >
< b > 11.< / b >
測試
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "11.1" data-path = "ch11/ch11-01.html" >
< a href = "../ch11/ch11-01.html" >
< i class = "fa fa-check" > < / i >
< b > 11.1.< / b >
go test
< / a >
< / li >
< li class = "chapter " data-level = "11.2" data-path = "ch11/ch11-02.html" >
< a href = "../ch11/ch11-02.html" >
< i class = "fa fa-check" > < / i >
< b > 11.2.< / b >
測試函數
< / a >
< / li >
< li class = "chapter " data-level = "11.3" data-path = "ch11/ch11-03.html" >
< a href = "../ch11/ch11-03.html" >
< i class = "fa fa-check" > < / i >
< b > 11.3.< / b >
測試覆蓋率
< / a >
< / li >
< li class = "chapter " data-level = "11.4" data-path = "ch11/ch11-04.html" >
< a href = "../ch11/ch11-04.html" >
< i class = "fa fa-check" > < / i >
< b > 11.4.< / b >
基準測試
< / a >
< / li >
< li class = "chapter " data-level = "11.5" data-path = "ch11/ch11-05.html" >
< a href = "../ch11/ch11-05.html" >
< i class = "fa fa-check" > < / i >
< b > 11.5.< / b >
剖析
< / a >
< / li >
< li class = "chapter " data-level = "11.6" data-path = "ch11/ch11-06.html" >
< a href = "../ch11/ch11-06.html" >
< i class = "fa fa-check" > < / i >
< b > 11.6.< / b >
示例函數
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "12" data-path = "ch12/ch12.html" >
< a href = "../ch12/ch12.html" >
< i class = "fa fa-check" > < / i >
< b > 12.< / b >
反射
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "12.1" data-path = "ch12/ch12-01.html" >
< a href = "../ch12/ch12-01.html" >
< i class = "fa fa-check" > < / i >
< b > 12.1.< / b >
2015-12-21 04:55:18 +00:00
爲何需要反射?
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "12.2" data-path = "ch12/ch12-02.html" >
< a href = "../ch12/ch12-02.html" >
< i class = "fa fa-check" > < / i >
< b > 12.2.< / b >
reflect.Type和reflect.Value
< / a >
< / li >
< li class = "chapter " data-level = "12.3" data-path = "ch12/ch12-03.html" >
< a href = "../ch12/ch12-03.html" >
< i class = "fa fa-check" > < / i >
< b > 12.3.< / b >
Display遞歸打印
< / a >
< / li >
< li class = "chapter " data-level = "12.4" data-path = "ch12/ch12-04.html" >
< a href = "../ch12/ch12-04.html" >
< i class = "fa fa-check" > < / i >
< b > 12.4.< / b >
2015-12-21 04:55:18 +00:00
示例: 編碼S表達式
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "12.5" data-path = "ch12/ch12-05.html" >
< a href = "../ch12/ch12-05.html" >
< i class = "fa fa-check" > < / i >
< b > 12.5.< / b >
通過reflect.Value脩改值
< / a >
< / li >
< li class = "chapter " data-level = "12.6" data-path = "ch12/ch12-06.html" >
< a href = "../ch12/ch12-06.html" >
< i class = "fa fa-check" > < / i >
< b > 12.6.< / b >
2015-12-21 04:55:18 +00:00
示例: 解碼S表達式
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " data-level = "12.7" data-path = "ch12/ch12-07.html" >
< a href = "../ch12/ch12-07.html" >
< i class = "fa fa-check" > < / i >
< b > 12.7.< / b >
穫取結構體字段標識
< / a >
< / li >
< li class = "chapter " data-level = "12.8" data-path = "ch12/ch12-08.html" >
< a href = "../ch12/ch12-08.html" >
< i class = "fa fa-check" > < / i >
< b > 12.8.< / b >
顯示一個類型的方法集
< / a >
< / li >
< li class = "chapter " data-level = "12.9" data-path = "ch12/ch12-09.html" >
< a href = "../ch12/ch12-09.html" >
< i class = "fa fa-check" > < / i >
< b > 12.9.< / b >
幾點忠告
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "13" data-path = "ch13/ch13.html" >
< a href = "../ch13/ch13.html" >
< i class = "fa fa-check" > < / i >
< b > 13.< / b >
底層編程
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "13.1" data-path = "ch13/ch13-01.html" >
< a href = "../ch13/ch13-01.html" >
< i class = "fa fa-check" > < / i >
< b > 13.1.< / b >
unsafe.Sizeof, Alignof 和 Offsetof
< / a >
< / li >
< li class = "chapter " data-level = "13.2" data-path = "ch13/ch13-02.html" >
< a href = "../ch13/ch13-02.html" >
< i class = "fa fa-check" > < / i >
< b > 13.2.< / b >
unsafe.Pointer
< / a >
< / li >
< li class = "chapter " data-level = "13.3" data-path = "ch13/ch13-03.html" >
< a href = "../ch13/ch13-03.html" >
< i class = "fa fa-check" > < / i >
< b > 13.3.< / b >
示例: 深度相等判斷
< / a >
< / li >
< li class = "chapter " data-level = "13.4" data-path = "ch13/ch13-04.html" >
< a href = "../ch13/ch13-04.html" >
< i class = "fa fa-check" > < / i >
< b > 13.4.< / b >
通過cgo調用C代碼
< / a >
< / li >
< li class = "chapter " data-level = "13.5" data-path = "ch13/ch13-05.html" >
< a href = "../ch13/ch13-05.html" >
< i class = "fa fa-check" > < / i >
< b > 13.5.< / b >
幾點忠告
< / a >
< / li >
< / ul >
< / li >
2015-12-24 06:47:06 +00:00
< li class = "chapter " data-level = "14" data-path = "CONTRIBUTORS.html" >
2015-12-09 07:57:17 +00:00
2015-12-24 06:47:06 +00:00
< a href = "../CONTRIBUTORS.html" >
2015-12-09 07:57:17 +00:00
< i class = "fa fa-check" > < / i >
2015-12-21 04:55:18 +00:00
< b > 14.< / b >
2015-12-09 07:57:17 +00:00
2015-12-24 06:47:06 +00:00
附録
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "divider" > < / li >
< li >
< a href = "https://www.gitbook.com" target = "blank" class = "gitbook-link" >
本書使用 GitBook 釋出
< / a >
< / li >
< / ul >
< / nav >
< / div >
< div class = "book-body" >
< div class = "body-inner" >
< div class = "book-header" role = "navigation" >
<!-- Actions Left -->
<!-- Title -->
< h1 >
< i class = "fa fa-circle-o-notch fa-spin" > < / i >
< a href = "../" > Go编程语言< / a >
< / h1 >
< / div >
< div class = "page-wrapper" tabindex = "-1" role = "main" >
< div class = "page-inner" >
< section class = "normal" id = "section-" >
< h2 id = "17-web服務" > 1.7. Web服 務 < / h2 >
2015-12-24 06:47:06 +00:00
< p > Go語 言 的 內 置 庫 讓 我 們 寫 一 個 像 fetch這 樣 例 子 的 web服 務 器 變 得 異 常 地 簡 單 。 在 本 節 中 , 我 們 會 展 示 一 個 微 型 服 務 器 , 這 個 服 務 的 功 能 是 返 迴 當 前 用 戶 正 在 訪 問 的 URL。 也 就 是 説 比 如 用 戶 訪 問 的 是 < a href = "http://localhost:8000/hello" target = "_blank" > http://localhost:8000/hello< / a > , 那 麽 響 應 是 URL.Path = " hello" 。 < / p >
2015-12-09 07:57:17 +00:00
< pre > < code class = "lang-go" > gopl.io/ch1/server1
< span class = "hljs-comment" > // Server1 is a minimal " echo" server.< / span >
< span class = "hljs-keyword" > package< / span > main
< span class = "hljs-keyword" > import< / span > (
< span class = "hljs-string" > " fmt" < / span >
< span class = "hljs-string" > " log" < / span >
< span class = "hljs-string" > " net/http" < / span >
)
< span class = "hljs-keyword" > func< / span > main() {
http.HandleFunc(< span class = "hljs-string" > " /" < / span > , handler) < span class = "hljs-comment" > // each request calls handler< / span >
log.Fatal(http.ListenAndServe(< span class = "hljs-string" > " localhost:8000" < / span > , < span class = "hljs-constant" > nil< / span > ))
}
< span class = "hljs-comment" > // handler echoes the Path component of the request URL r.< / span >
< span class = "hljs-keyword" > func< / span > handler(w http.ResponseWriter, r *http.Request) {
2015-12-24 06:47:06 +00:00
fmt.Fprintf(w, < span class = "hljs-string" > " URL.Path = %q\n" < / span > , r.URL.Path)
2015-12-09 07:57:17 +00:00
}
< / code > < / pre >
2015-12-24 06:47:06 +00:00
< p > 我 們 隻 用 了 八 九 行 代 碼 就 實 現 了 一 個 個 Web服 務 程 序 , 這 都 是 多 虧 了 標 準 庫 里 的 方 法 已 經 幫 我 們 處 理 了 大 量 的 工 作 。 main函 數 會 將 所 有 發 送 到 /路 徑 下 的 請 求 和 handler函 數 關 聯 起 來 , /開 頭 的 請 求 其 實 就 是 所 有 發 送 到 當 前 站 點 上 的 請 求 , 我 們 的 服 務 跑 在 了 8000端 口 上 。 發 送 到 這 個 服 務 的 “ 請 求 ” 是 一 個 http.Request類 型 的 對 象 , 這 個 對 象 中 包 含 了 請 求 中 的 一 繫 列 相 關 字 段 , 其 中 就 包 括 我 們 需 要 的 URL。 當 請 求 到 達 服 務 器 時 , 這 個 請 求 會 被 傳 給 handler函 數 來 處 理 , 這 個 函 數 會 將 /hello這 個 路 徑 從 請 求 的 URL中 解 析 齣 來 , 然 後 把 其 發 送 到 響 應 中 , 這 里 我 們 用 的 是 標 準 輸 齣 流 的 fmt.Fprintf。 Web服 務 會 在 第 7.7節 中 詳 細 闡 述 。 < / p >
2015-12-21 04:55:18 +00:00
< p > 讓 我 們 在 後 颱 運 行 這 個 服 務 程 序 。 如 果 你 的 操 作 繫 統 是 Mac OS X或 者 Linux, 那 麽 在 運 行 命 令 的 末 尾 加 上 一 個 & 符 號 , 卽 可 讓 程 序 簡 單 地 跑 在 後 颱 , 而 在 windows下 , 你 需 要 在 另 外 一 個 命 令 行 窗 口 去 運 行 這 個 程 序 了 。 < / p >
2015-12-09 07:57:17 +00:00
< pre > < code > $ go run src/gopl.io/ch1/server1/main.go &
2015-12-21 04:55:18 +00:00
< / code > < / pre > < p > 現 在 我 們 可 以 通 過 命 令 行 來 發 送 客 戶 端 請 求 了 : < / p >
2015-12-09 07:57:17 +00:00
< pre > < code > $ go build gopl.io/ch1/fetch
$ ./fetch http://localhost:8000
URL.Path = " /"
$ ./fetch http://localhost:8000/help
URL.Path = " /help"
2015-12-24 06:47:06 +00:00
< / code > < / pre > < p > 另 外 我 們 還 可 以 直 接 在 瀏 覽 器 里 訪 問 這 個 URL, 然 後 得 到 返 迴 結 果 , 如 圖 1.2: < / p >
< p > < img src = "../images/ch1-02.png" alt = "" > < / p >
2015-12-21 04:55:18 +00:00
< p > 在 這 個 服 務 的 基 礎 上 疊 加 特 性 是 很 容 易 的 。 一 種 比 較 實 用 的 脩 改 是 爲 訪 問 的 url添 加 某 種 狀 態 。 比 如 , 下 面 這 個 版 本 輸 齣 了 同 樣 的 內 容 , 但 是 會 對 請 求 的 次 數 進 行 計 算 ; 對 URL的 請 求 結 果 會 包 含 各 種 URL被 訪 問 的 總 次 數 , 直 接 對 /count這 個 URL的 訪 問 要 除 外 。 < / p >
2015-12-09 07:57:17 +00:00
< pre > < code class = "lang-go" > gopl.io/ch1/server2
< span class = "hljs-comment" > // Server2 is a minimal " echo" and counter server.< / span >
< span class = "hljs-keyword" > package< / span > main
< span class = "hljs-keyword" > import< / span > (
< span class = "hljs-string" > " fmt" < / span >
< span class = "hljs-string" > " log" < / span >
< span class = "hljs-string" > " net/http" < / span >
< span class = "hljs-string" > " sync" < / span >
)
< span class = "hljs-keyword" > var< / span > mu sync.Mutex
< span class = "hljs-keyword" > var< / span > count < span class = "hljs-typename" > int< / span >
< span class = "hljs-keyword" > func< / span > main() {
http.HandleFunc(< span class = "hljs-string" > " /" < / span > , handler)
http.HandleFunc(< span class = "hljs-string" > " /count" < / span > , counter)
log.Fatal(http.ListenAndServe(< span class = "hljs-string" > " localhost:8000" < / span > , < span class = "hljs-constant" > nil< / span > ))
}
< span class = "hljs-comment" > // handler echoes the Path component of the requested URL.< / span >
< span class = "hljs-keyword" > func< / span > handler(w http.ResponseWriter, r *http.Request) {
mu.Lock()
count++
mu.Unlock()
fmt.Fprintf(w, < span class = "hljs-string" > " URL.Path = %q\n" < / span > , r.URL.Path)
}
< span class = "hljs-comment" > // counter echoes the number of calls so far.< / span >
< span class = "hljs-keyword" > func< / span > counter(w http.ResponseWriter, r *http.Request) {
mu.Lock()
fmt.Fprintf(w, < span class = "hljs-string" > " Count %d\n" < / span > , count)
mu.Unlock()
}
< / code > < / pre >
2015-12-24 06:47:06 +00:00
< p > 這 個 服 務 器 有 兩 個 請 求 處 理 函 數 , 請 求 的 url會 決 定 具 體 調 用 哪 一 個 : 對 /count這 個 url的 請 求 會 調 用 到 count這 個 函 數 , 其 它 所 有 的 url都 會 調 用 默 認 的 處 理 函 數 。 如 果 你 的 請 求 pattern是 以 /結 尾 , 那 麽 所 有 以 該 url爲 前 綴 的 url都 會 被 這 條 規 則 匹 配 。 在 這 些 代 碼 的 背 後 , 服 務 器 每 一 次 接 收 請 求 處 理 時 都 會 另 起 一 個 goroutine, 這 樣 服 務 器 就 可 以 同 一 時 間 處 理 多 數 請 求 。 然 而 在 併 發 情 況 下 , 假 如 眞 的 有 兩 個 請 求 同 一 時 刻 去 更 新 count, 那 麽 這 個 值 可 能 併 不 會 被 正 確 地 增 加 ; 這 個 程 序 可 能 會 被 引 發 一 個 嚴 重 的 bug: 競 態 條 件 ( 參 見 9.1) 。 爲 了 避 免 這 個 問 題 , 我 們 必 鬚 保 證 每 次 脩 改 變 量 的 最 多 隻 能 有 一 個 goroutine, 這 也 就 是 代 碼 里 的 mu.Lock()和 mu.Unlock()調 用 將 脩 改 count的 所 有 行 爲 包 在 中 間 的 目 的 。 第 九 章 中 我 們 會 進 一 步 講 解 共 享 變 量 。 < / p >
< p > 下 面 是 一 個 更 爲 豐 富 的 例 子 , handler函 數 會 把 請 求 的 http頭 和 請 求 的 form數 據 都 打 印 齣 來 , 這 樣 可 以 讓 檢 査 和 調 試 這 個 服 務 更 爲 方 便 : < / p >
2015-12-09 07:57:17 +00:00
< pre > < code class = "lang-go" > gopl.io/ch1/server3
< span class = "hljs-comment" > // handler echoes the HTTP request.< / span >
< span class = "hljs-keyword" > func< / span > handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, < span class = "hljs-string" > " %s %s %s\n" < / span > , r.Method, r.URL, r.Proto)
< span class = "hljs-keyword" > for< / span > k, v := < span class = "hljs-keyword" > range< / span > r.Header {
fmt.Fprintf(w, < span class = "hljs-string" > " Header[%q] = %q\n" < / span > , k, v)
}
fmt.Fprintf(w, < span class = "hljs-string" > " Host = %q\n" < / span > , r.Host)
fmt.Fprintf(w, < span class = "hljs-string" > " RemoteAddr = %q\n" < / span > , r.RemoteAddr)
< span class = "hljs-keyword" > if< / span > err := r.ParseForm(); err != < span class = "hljs-constant" > nil< / span > {
log.Print(err)
}
< span class = "hljs-keyword" > for< / span > k, v := < span class = "hljs-keyword" > range< / span > r.Form {
2015-12-24 06:47:06 +00:00
fmt.Fprintf(w, < span class = "hljs-string" > " Form[%q] = %q\n" < / span > , k, v)
2015-12-09 07:57:17 +00:00
}
}
< / code > < / pre >
2015-12-21 04:55:18 +00:00
< p > 我 們 用 http.Request這 個 struct里 的 字 段 來 輸 齣 下 面 這 樣 的 內 容 : < / p >
2015-12-09 07:57:17 +00:00
< pre > < code > GET /?q=query HTTP/1.1
Header[" Accept-Encoding" ] = [" gzip, deflate, sdch" ] Header[" Accept-Language" ] = [" en-US,en;q=0.8" ]
Header[" Connection" ] = [" keep-alive" ]
Header[" Accept" ] = [" text/html,application/xhtml+xml,application/xml;..." ] Header[" User-Agent" ] = [" Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5)..." ] Host = " localhost:8000"
RemoteAddr = " 127.0.0.1:59911"
Form[" q" ] = [" query" ]
2015-12-24 06:47:06 +00:00
< / code > < / pre > < p > 可 以 看 到 這 里 的 ParseForm被 嵌 套 在 了 if語 句 中 。 Go語 言 允 許 這 樣 的 一 個 簡 單 的 語 句 結 果 作 爲 循 環 的 變 量 聲 明 齣 現 在 if語 句 的 最 前 面 , 這 一 點 對 錯 誤 處 理 很 有 用 處 。 我 們 還 可 以 像 下 面 這 樣 寫 ( 當 然 看 起 來 就 長 了 一 些 ) : < / p >
2015-12-09 07:57:17 +00:00
< pre > < code class = "lang-go" > err := r.ParseForm()
< span class = "hljs-keyword" > if< / span > err != < span class = "hljs-constant" > nil< / span > {
log.Print(err)
}
< / code > < / pre >
2015-12-21 04:55:18 +00:00
< p > 用 if和 ParseForm結 合 可 以 讓 代 碼 更 加 簡 單 , 併 且 可 以 限 製 err這 個 變 量 的 作 用 域 , 這 麽 做 是 很 不 錯 的 。 我 們 會 在 2.7節 中 講 解 作 用 域 。 < / p >
< p > 在 這 些 程 序 中 , 我 們 看 到 了 很 多 不 同 的 類 型 被 輸 齣 到 標 準 輸 齣 流 中 。 比 如 前 面 的 fetch程 序 , 就 把 HTTP的 響 應 數 據 拷 貝 到 了 os.Stdout, 或 者 在 lissajous程 序 里 我 們 輸 齣 的 是 一 個 文 件 。 fetchall程 序 則 完 全 忽 略 到 了 HTTP的 響 應 體 , 隻 是 計 算 了 一 下 響 應 體 的 大 小 , 這 個 程 序 中 把 響 應 體 拷 貝 到 了 ioutil.Discard。 在 本 節 的 web服 務 器 程 序 中 則 是 用 fmt.Fprintf直 接 寫 到 了 http.ResponseWriter中 。 < / p >
< p > 盡 管 這 三 種 具 體 的 實 現 流 程 併 不 太 一 樣 , 他 們 都 實 現 一 個 共 同 的 接 口 , 卽 當 它 們 被 調 用 需 要 一 個 標 準 流 輸 齣 時 都 可 以 滿 足 。 這 個 接 口 叫 作 io.Writer, 在 7.1節 中 會 詳 細 討 論 。 < / p >
2015-12-24 06:47:06 +00:00
< p > Go語 言 的 接 口 機 製 會 在 第 7章 中 講 解 , 爲 了 在 這 里 簡 單 説 明 接 口 能 做 什 麽 , 讓 我 們 簡 單 地 將 這 里 的 web服 務 器 和 之 前 寫 的 lissajous函 數 結 合 起 來 , 這 樣 GIF動 畵 可 以 被 寫 到 HTTP的 客 戶 端 , 而 不 是 之 前 的 標 準 輸 齣 流 。 隻 要 在 web服 務 器 的 代 碼 里 加 入 下 面 這 幾 行 。 < / p >
< pre > < code class = "lang-Go" > handler := < span class = "hljs-keyword" > func< / span > (w http.ResponseWriter, r *http.Request) {
lissajous(w)
2015-12-09 07:57:17 +00:00
}
2015-12-24 06:47:06 +00:00
http.HandleFunc(< span class = "hljs-string" > " /" < / span > , handler)
< / code > < / pre >
< p > 或 者 另 一 種 等 價 形 式 : < / p >
< pre > < code class = "lang-Go" > http.HandleFunc(< span class = "hljs-string" > " /" < / span > , < span class = "hljs-keyword" > func< / span > (w http.ResponseWriter, r *http.Request) {
2015-12-09 07:57:17 +00:00
lissajous(w)
})
2015-12-24 06:47:06 +00:00
< / code > < / pre >
< p > HandleFunc函 數 的 第 二 個 參 數 是 一 個 函 數 的 字 面 值 , 也 就 是 一 個 在 使 用 時 定 義 的 匿 名 函 數 。 這 些 內 容 我 們 會 在 5.6節 中 講 解 。 < / p >
< p > 做 完 這 些 脩 改 之 後 , 在 瀏 覽 器 里 訪 問 < a href = "http://localhost:8000" target = "_blank" > http://localhost:8000< / a > 。 每 次 你 載 入 這 個 頁 面 都 可 以 看 到 一 個 像 圖 1.3那 樣 的 動 畵 。 < / p >
< p > < strong > 練 習 1.12: < / strong > 脩 改 Lissajour服 務 , 從 URL讀 取 變 量 , 比 如 你 可 以 訪 問 < a href = "http://localhost:8000/?cycles=20" target = "_blank" > http://localhost:8000/?cycles=20< / a > 這 個 URL, 這 樣 訪 問 可 以 將 程 序 里 的 cycles默 認 的 5脩 改 爲 20。 字 符 串 轉 換 爲 數 字 可 以 調 用 strconv.Atoi函 數 。 你 可 以 在 dodoc里 査 看 strconv.Atoi的 詳 細 説 明 。 < / p >
< p > < img src = "../images/ch1-03.png" alt = "" > < / p >
2015-12-09 07:57:17 +00:00
< / section >
< / div >
< / div >
< / div >
2015-12-21 04:55:18 +00:00
< a href = "../ch1/ch1-06.html" class = "navigation navigation-prev " aria-label = "Previous page: 併發穫取多個URL" > < i class = "fa fa-angle-left" > < / i > < / a >
2015-12-09 07:57:17 +00:00
< a href = "../ch1/ch1-08.html" class = "navigation navigation-next " aria-label = "Next page: 本章要點" > < i class = "fa fa-angle-right" > < / i > < / a >
< / div >
< / div >
< script src = "../gitbook/app.js" > < / script >
< script src = "../gitbook/plugins/gitbook-plugin-search/lunr.min.js" > < / script >
< script src = "../gitbook/plugins/gitbook-plugin-search/search.js" > < / script >
< script src = "../gitbook/plugins/gitbook-plugin-sharing/buttons.js" > < / script >
< script src = "../gitbook/plugins/gitbook-plugin-fontsettings/buttons.js" > < / script >
< script >
require(["gitbook"], function(gitbook) {
var config = {"highlight":{},"search":{},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2}};
gitbook.start(config);
});
< / script >
< / body >
< / html >