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" / >
2015-12-31 08:20:27 +00:00
< title > 結構體 | Go语言圣经< / title >
2015-12-09 07:57:17 +00:00
< 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" >
2015-12-28 08:08:26 +00:00
< link rel = "stylesheet" href = "../gitbook/plugins/gitbook-plugin-katex/katex.min.css" >
2015-12-09 07:57:17 +00:00
< link rel = "stylesheet" href = "../gitbook/plugins/gitbook-plugin-highlight/website.css" >
< link rel = "stylesheet" href = "../gitbook/plugins/gitbook-plugin-fontsettings/website.css" >
< link rel = "next" href = "../ch4/ch4-05.html" / >
< link rel = "prev" href = "../ch4/ch4-03.html" / >
< / head >
< body >
2015-12-31 08:20:27 +00:00
< div class = "book" data-level = "4.4" data-chapter-title = "結構體" data-filepath = "ch4/ch4-04.md" data-basepath = ".." data-revision = "Thu Dec 31 2015 16:18:40 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 >
2015-12-28 08:08:26 +00:00
獲取URL
2015-12-09 07:57:17 +00:00
< / 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-28 08:08:26 +00:00
併發獲取多個URL
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter " 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 >
2015-12-31 08:20:27 +00:00
Slice
2015-12-09 07:57:17 +00:00
< / 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 >
2015-12-31 08:20:27 +00:00
Map
2015-12-09 07:57:17 +00:00
< / a >
< / li >
< li class = "chapter active" 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 >
2015-12-28 08:08:26 +00:00
Recover捕獲異常
2015-12-09 07:57:17 +00:00
< / 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-28 08:08:26 +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 >
2015-12-28 08:08:26 +00:00
獲取結構體字段標識
2015-12-09 07:57:17 +00:00
< / 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 >
2015-12-31 08:20:27 +00:00
< a href = "../" > Go语言圣经< / a >
2015-12-09 07:57:17 +00:00
< / h1 >
< / div >
< div class = "page-wrapper" tabindex = "-1" role = "main" >
< div class = "page-inner" >
< section class = "normal" id = "section-" >
< h2 id = "44-結構體" > 4.4. 結 構 體 < / h2 >
2015-12-31 08:20:27 +00:00
< p > 結 構 體 是 一 種 聚 合 的 數 據 類 型 , 由 零 個 或 多 個 任 意 類 型 的 值 聚 合 成 的 實 體 。 每 個 值 稱 爲 結 構 體 的 成 員 。 是 用 結 構 體 的 經 典 案 例 處 理 公 司 的 員 工 信 息 , 每 個 員 工 信 息 包 含 一 個 唯 一 的 員 工 編 號 、 員 工 的 名 字 、 家 庭 住 址 、 出 生 日 期 、 工 作 崗 位 、 薪 資 、 上 級 領 導 等 等 。 所 有 的 這 些 成 員 都 需 要 綁 定 到 一 個 實 體 , 可 以 作 爲 一 個 整 體 單 元 被 複 製 , 作 爲 函 數 的 參 數 或 返 迴 值 , 或 者 是 被 存 儲 到 數 組 中 , 等 等 。 < / p >
< p > 下 面 兩 個 語 句 分 别 聲 明 了 一 個 叫 Employee的 結 構 體 類 型 , 併 且 聲 明 了 一 個 Employee類 型 的 變 量 dilbert: < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > type< / span > Employee < span class = "hljs-keyword" > struct< / span > {
ID < span class = "hljs-typename" > int< / span >
Name < span class = "hljs-typename" > string< / span >
Address < span class = "hljs-typename" > string< / span >
DoB time.Time
Position < span class = "hljs-typename" > string< / span >
Salary < span class = "hljs-typename" > int< / span >
ManagerID < span class = "hljs-typename" > int< / span >
}
< span class = "hljs-keyword" > var< / span > dilbert Employee
< / code > < / pre >
< p > dilbert結 構 體 變 量 的 成 員 可 以 通 過 點 操 作 符 訪 問 , 比 如 dilbert.Name和 dilbert.DoB。 因 爲 dilbert是 一 個 變 量 , 它 所 有 的 成 員 也 同 樣 是 變 量 , 我 們 可 以 對 每 個 成 員 賦 值 : < / p >
< pre > < code class = "lang-Go" > dilbert.Salary -= < span class = "hljs-number" > 5000< / span > < span class = "hljs-comment" > // demoted, for writing too few lines of code< / span >
< / code > < / pre >
< p > 或 者 是 對 成 員 取 地 址 , 然 後 通 過 指 針 訪 問 : < / p >
< pre > < code class = "lang-Go" > position := & dilbert.Position
*position = < span class = "hljs-string" > " Senior " < / span > + *position < span class = "hljs-comment" > // promoted, for outsourcing to Elbonia< / span >
< / code > < / pre >
< p > 點 操 作 符 也 可 以 和 指 向 結 構 體 的 指 針 一 起 工 作 : < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > var< / span > employeeOfTheMonth *Employee = & dilbert
employeeOfTheMonth.Position += < span class = "hljs-string" > " (proactive team player)" < / span >
< / code > < / pre >
< p > 相 當 於 下 面 語 句 < / p >
< pre > < code class = "lang-Go" > (*employeeOfTheMonth).Position += < span class = "hljs-string" > " (proactive team player)" < / span >
< / code > < / pre >
< p > EmployeeByID函 數 將 根 據 給 定 的 員 工 ID返 迴 對 應 的 員 工 信 息 結 構 體 的 指 針 。 我 們 可 以 使 用 點 操 作 符 來 訪 問 它 里 面 的 成 員 : < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > func< / span > EmployeeByID(id < span class = "hljs-typename" > int< / span > ) *Employee { < span class = "hljs-comment" > /* ... */< / span > }
fmt.Println(EmployeeByID(dilbert.ManagerID).Position) < span class = "hljs-comment" > // " Pointy-haired boss" < / span >
id := dilbert.ID
EmployeeByID(id).Salary = < span class = "hljs-number" > 0< / span > < span class = "hljs-comment" > // fired for... no real reason< / span >
< / code > < / pre >
< p > 後 面 的 語 句 通 過 EmployeeByID返 迴 的 結 構 體 指 針 更 新 了 Employee結 構 體 的 成 員 。 如 果 將 EmployeeByID函 數 的 返 迴 值 從 < code > *Employee< / code > 指 針 類 型 改 爲 Employee值 類 型 , 那 麽 更 新 語 句 將 不 能 編 譯 通 過 , 因 爲 在 賦 值 語 句 的 左 邊 併 不 確 定 是 一 個 變 量 。 < / p >
< p > 通 常 一 行 對 應 一 個 結 構 體 成 員 , 成 員 的 名 字 在 前 類 型 在 後 , 不 過 如 果 相 鄰 的 成 員 類 型 如 果 相 同 的 話 可 以 被 合 併 到 一 行 , 就 像 下 面 的 Name和 Address成 員 那 樣 : < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > type< / span > Employee < span class = "hljs-keyword" > struct< / span > {
ID < span class = "hljs-typename" > int< / span >
Name, Address < span class = "hljs-typename" > string< / span >
DoB time.Time
Position < span class = "hljs-typename" > string< / span >
Salary < span class = "hljs-typename" > int< / span >
ManagerID < span class = "hljs-typename" > int< / span >
}
< / code > < / pre >
< p > 結 構 體 成 員 的 輸 入 順 序 也 有 重 要 的 意 義 。 我 們 也 可 以 將 Position成 員 合 併 ( 因 爲 也 是 字 符 串 類 型 ) , 或 者 是 交 換 Name和 Address出 現 的 先 後 順 序 , 那 樣 的 話 就 是 定 義 了 不 同 的 結 構 體 類 型 。 通 常 , 我 們 隻 是 將 相 關 的 成 員 合 併 到 一 起 。 < / p >
< p > 如 果 結 構 體 成 員 名 字 是 以 大 寫 字 母 開 頭 的 , 那 麽 該 成 員 就 是 導 出 的 ; 這 是 Go語 言 導 出 規 則 決 定 的 。 一 個 結 構 體 可 能 同 時 包 含 導 出 和 未 導 出 的 成 員 。 < / p >
< p > 結 構 體 類 型 往 往 是 冗 長 的 , 因 爲 它 的 每 個 成 員 可 能 都 會 占 一 行 。 雖 然 我 們 每 次 都 可 以 重 寫 整 個 結 構 體 成 員 , 但 是 重 複 會 令 人 厭 煩 。 因 此 , 完 整 的 結 構 體 寫 法 通 常 隻 在 類 型 聲 明 語 句 的 地 方 出 現 , 就 像 Employee類 型 聲 明 語 句 那 樣 。 < / p >
< p > 一 個 命 名 爲 S的 結 構 體 類 型 將 不 能 再 包 含 S類 型 的 成 員 : 一 個 聚 合 的 值 不 能 包 含 它 自 身 。 ( 該 限 製 同 樣 適 應 於 數 組 。 ) 但 是 S類 型 的 結 構 體 可 以 包 含 < code > *S< / code > 指 針 類 型 的 成 員 , 這 可 以 讓 我 們 創 建 遞 歸 的 數 據 結 構 , 比 如 鏈 表 和 樹 結 構 等 。 在 下 面 的 代 碼 中 , 我 們 使 用 一 個 二 叉 樹 來 實 現 一 個 插 入 排 序 : < / p >
< pre > < code class = "lang-Go" > gopl.io/ch4/treesort
< span class = "hljs-keyword" > type< / span > tree < span class = "hljs-keyword" > struct< / span > {
value < span class = "hljs-typename" > int< / span >
left, right *tree
}
< span class = "hljs-comment" > // Sort sorts values in place.< / span >
< span class = "hljs-keyword" > func< / span > Sort(values []< span class = "hljs-typename" > int< / span > ) {
< span class = "hljs-keyword" > var< / span > root *tree
< span class = "hljs-keyword" > for< / span > _, v := < span class = "hljs-keyword" > range< / span > values {
root = add(root, v)
}
appendValues(values[:< span class = "hljs-number" > 0< / span > ], root)
}
< span class = "hljs-comment" > // appendValues appends the elements of t to values in order< / span >
< span class = "hljs-comment" > // and returns the resulting slice.< / span >
< span class = "hljs-keyword" > func< / span > appendValues(values []< span class = "hljs-typename" > int< / span > , t *tree) []< span class = "hljs-typename" > int< / span > {
< span class = "hljs-keyword" > if< / span > t != < span class = "hljs-constant" > nil< / span > {
values = appendValues(values, t.left)
values = < span class = "hljs-built_in" > append< / span > (values, t.value)
values = appendValues(values, t.right)
}
< span class = "hljs-keyword" > return< / span > values
}
< span class = "hljs-keyword" > func< / span > add(t *tree, value < span class = "hljs-typename" > int< / span > ) *tree {
< span class = "hljs-keyword" > if< / span > t == < span class = "hljs-constant" > nil< / span > {
< span class = "hljs-comment" > // Equivalent to return & tree{value: value}.< / span >
t = < span class = "hljs-built_in" > new< / span > (tree)
t.value = value
< span class = "hljs-keyword" > return< / span > t
}
< span class = "hljs-keyword" > if< / span > value < t.value {
t.left = add(t.left, value)
} < span class = "hljs-keyword" > else< / span > {
t.right = add(t.right, value)
}
< span class = "hljs-keyword" > return< / span > t
}
< / code > < / pre >
< p > 結 構 體 類 型 的 零 值 是 每 個 成 員 都 對 是 零 值 。 通 常 會 將 零 值 作 爲 最 合 理 的 默 認 值 。 例 如 , 在 bytes.Buffer類 型 , 結 構 體 初 始 值 就 是 一 個 隨 時 可 用 的 空 緩 存 , 還 有 在 第 9章 將 會 講 到 的 sync.Mutex的 零 值 也 是 有 效 的 未 鎖 狀 態 。 有 時 候 這 種 零 值 可 用 的 特 性 是 自 然 獲 得 的 , 但 是 也 有 些 類 型 需 要 一 些 額 外 的 工 作 。 < / p >
< p > 如 果 結 構 體 沒 有 任 何 成 員 的 話 就 是 空 結 構 體 , 寫 作 struct{}。 它 的 大 小 爲 0, 也 不 包 含 任 何 信 息 , 但 是 有 時 候 依 然 是 有 價 值 的 。 有 些 Go語 言 程 序 員 用 map帶 模 擬 set數 據 結 構 時 , 用 它 來 代 替 map中 布 爾 類 型 的 value, 隻 是 強 調 key的 重 要 性 , 但 是 因 爲 節 約 的 空 間 有 限 , 而 且 語 法 比 較 複 雜 , 所 有 我 們 通 常 避 免 避 免 這 樣 的 用 法 。 < / p >
< pre > < code class = "lang-Go" > seen := < span class = "hljs-built_in" > make< / span > (< span class = "hljs-keyword" > map< / span > [< span class = "hljs-typename" > string< / span > ]< span class = "hljs-keyword" > struct< / span > {}) < span class = "hljs-comment" > // set of strings< / span >
< span class = "hljs-comment" > // ...< / span >
< span class = "hljs-keyword" > if< / span > _, ok := seen[s]; !ok {
seen[s] = < span class = "hljs-keyword" > struct< / span > {}{}
< span class = "hljs-comment" > // ...first time seeing s...< / span >
}
< / code > < / pre >
2015-12-28 08:08:26 +00:00
< h3 id = "441-結構體面值" > 4.4.1. 結 構 體 面 值 < / h3 >
2015-12-31 08:20:27 +00:00
< p > 結 構 體 值 可 以 用 結 構 體 面 值 表 示 , 結 構 體 面 值 可 以 指 定 每 個 成 員 的 值 。 < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > type< / span > Point < span class = "hljs-keyword" > struct< / span > { X, Y < span class = "hljs-typename" > int< / span > }
p := Point{< span class = "hljs-number" > 1< / span > , < span class = "hljs-number" > 2< / span > }
< / code > < / pre >
< p > 這 里 有 兩 種 形 式 的 結 構 體 面 值 語 法 , 上 面 的 是 第 一 種 寫 法 , 要 求 以 結 構 體 成 員 定 義 的 順 序 爲 每 個 結 構 體 成 員 指 定 一 個 面 值 。 它 要 求 寫 代 碼 和 讀 代 碼 的 人 要 記 住 結 構 體 的 每 個 成 員 的 類 型 和 順 序 , 併 且 結 構 體 成 員 有 細 微 的 調 整 就 可 能 導 致 上 述 代 碼 不 能 編 譯 。 因 此 , 上 述 的 語 法 一 般 隻 在 定 義 結 構 體 的 包 內 部 使 用 , 或 者 是 在 較 小 的 結 構 體 中 使 用 , 這 些 結 構 體 的 成 員 排 列 比 較 規 則 , 比 如 image.Point{x, y}或 color.RGBA{red, green, blue, alpha}。 < / p >
< p > 其 實 更 常 用 的 是 第 二 種 寫 法 , 以 成 員 名 字 和 相 應 的 值 來 初 始 化 , 可 以 包 含 部 分 或 全 部 的 成 員 , 如 1.4節 的 Lissajous程 序 的 寫 法 : < / p >
< pre > < code class = "lang-Go" > anim := gif.GIF{LoopCount: nframes}
< / code > < / pre >
< p > 在 這 種 形 式 的 結 構 體 面 值 寫 法 中 , 如 果 成 員 被 忽 略 的 話 將 默 認 用 零 值 。 因 爲 , 提 供 了 成 員 的 名 字 , 所 有 成 員 出 現 的 順 序 併 不 重 要 。 < / p >
< p > 兩 種 不 同 形 式 的 寫 法 不 能 混 合 使 用 。 而 且 , 你 不 能 企 圖 在 外 部 包 中 用 第 一 種 順 序 賦 值 的 技 巧 來 偷 偷 地 初 始 化 結 構 體 中 未 導 出 的 成 員 。 < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > package< / span > p
< span class = "hljs-keyword" > type< / span > T < span class = "hljs-keyword" > struct< / span > { a, b < span class = "hljs-typename" > int< / span > } < span class = "hljs-comment" > // a and b are not exported< / span >
< span class = "hljs-keyword" > package< / span > q
< span class = "hljs-keyword" > import< / span > < span class = "hljs-string" > " p" < / span >
< span class = "hljs-keyword" > var< / span > _ = p.T{a: < span class = "hljs-number" > 1< / span > , b: < span class = "hljs-number" > 2< / span > } < span class = "hljs-comment" > // compile error: can' t reference a, b< / span >
< span class = "hljs-keyword" > var< / span > _ = p.T{< span class = "hljs-number" > 1< / span > , < span class = "hljs-number" > 2< / span > } < span class = "hljs-comment" > // compile error: can' t reference a, b< / span >
< / code > < / pre >
< p > 雖 然 上 面 最 後 一 行 代 碼 的 編 譯 錯 誤 信 息 中 併 沒 有 顯 式 提 到 未 導 出 的 成 員 , 但 是 這 樣 企 圖 隱 式 使 用 未 導 出 成 員 的 行 爲 也 是 不 允 許 的 。 < / p >
< p > 結 構 體 可 以 作 爲 函 數 的 參 數 和 返 迴 值 。 例 如 , 這 個 Scale函 數 將 Point類 型 的 值 縮 放 後 返 迴 : < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > func< / span > Scale(p Point, factor < span class = "hljs-typename" > int< / span > ) Point {
< span class = "hljs-keyword" > return< / span > Point{p.X * factor, p.Y * factor}
}
fmt.Println(Scale(Point{< span class = "hljs-number" > 1< / span > , < span class = "hljs-number" > 2< / span > }, < span class = "hljs-number" > 5< / span > )) < span class = "hljs-comment" > // " {5 10}" < / span >
< / code > < / pre >
< p > 如 果 考 慮 效 率 的 話 , 較 大 的 結 構 體 通 常 會 用 指 針 的 方 式 傳 入 和 返 迴 , < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > func< / span > Bonus(e *Employee, percent < span class = "hljs-typename" > int< / span > ) < span class = "hljs-typename" > int< / span > {
< span class = "hljs-keyword" > return< / span > e.Salary * percent / < span class = "hljs-number" > 100< / span >
}
< / code > < / pre >
< p > 如 果 要 在 函 數 內 部 脩 改 結 構 體 成 員 的 話 , 用 指 針 傳 入 是 必 鬚 的 ; 因 爲 在 Go語 言 中 , 所 有 的 函 數 參 數 都 是 值 拷 貝 出 入 的 , 函 數 參 數 將 不 再 是 函 數 調 用 時 的 原 始 變 量 。 < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > func< / span > AwardAnnualRaise(e *Employee) {
e.Salary = e.Salary * < span class = "hljs-number" > 105< / span > / < span class = "hljs-number" > 100< / span >
}
< / code > < / pre >
< p > 因 爲 結 構 體 通 常 通 過 指 針 處 理 , 可 以 用 下 面 的 寫 法 來 創 建 併 初 始 化 一 個 結 構 體 變 量 , 併 返 迴 結 構 體 的 地 址 : < / p >
< pre > < code class = "lang-Go" > pp := & Point{< span class = "hljs-number" > 1< / span > , < span class = "hljs-number" > 2< / span > }
< / code > < / pre >
< p > 它 是 下 面 的 語 句 是 等 價 的 < / p >
< pre > < code class = "lang-Go" > pp := < span class = "hljs-built_in" > new< / span > (Point)
*pp = Point{< span class = "hljs-number" > 1< / span > , < span class = "hljs-number" > 2< / span > }
< / code > < / pre >
< p > 不 過 & Point{1, 2}寫 法 可 以 直 接 在 表 達 式 中 使 用 , 比 如 一 個 函 數 調 用 。 < / p >
2015-12-28 08:08:26 +00:00
< h3 id = "442-結構體比較" > 4.4.2. 結 構 體 比 較 < / h3 >
2015-12-31 08:20:27 +00:00
< p > 如 果 結 構 體 的 全 部 成 員 都 是 可 以 比 較 的 , 那 麽 結 構 體 也 是 可 以 比 較 的 , 那 樣 的 話 兩 個 結 構 體 將 可 以 使 用 ==或 !=運 算 符 進 行 比 較 。 相 等 比 較 運 算 符 ==將 比 較 兩 個 結 構 體 的 每 個 成 員 , 因 此 下 面 兩 個 比 較 的 表 達 式 是 等 價 的 : < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > type< / span > Point < span class = "hljs-keyword" > struct< / span > { X, Y < span class = "hljs-typename" > int< / span > }
p := Point{< span class = "hljs-number" > 1< / span > , < span class = "hljs-number" > 2< / span > }
q := Point{< span class = "hljs-number" > 2< / span > , < span class = "hljs-number" > 1< / span > }
fmt.Println(p.X == q.X & & p.Y == q.Y) < span class = "hljs-comment" > // " false" < / span >
fmt.Println(p == q) < span class = "hljs-comment" > // " false" < / span >
< / code > < / pre >
< p > 可 比 較 的 結 構 體 類 型 和 其 他 可 比 較 的 類 型 一 樣 , 可 以 用 於 map的 key類 型 。 < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > type< / span > address < span class = "hljs-keyword" > struct< / span > {
hostname < span class = "hljs-typename" > string< / span >
port < span class = "hljs-typename" > int< / span >
}
hits := < span class = "hljs-built_in" > make< / span > (< span class = "hljs-keyword" > map< / span > [address]< span class = "hljs-typename" > int< / span > )
hits[address{< span class = "hljs-string" > " golang.org" < / span > , < span class = "hljs-number" > 443< / span > }]++
< / code > < / pre >
2015-12-28 08:08:26 +00:00
< h3 id = "443-結構體嵌入和匿名成員" > 4.4.3. 結 構 體 嵌 入 和 匿 名 成 員 < / h3 >
2015-12-31 08:20:27 +00:00
< p > 在 本 節 中 , 我 們 將 看 到 如 果 使 用 Go語 言 提 供 的 不 同 尋 常 的 結 構 體 嵌 入 機 製 讓 一 個 命 名 的 結 構 體 包 含 另 一 個 結 構 體 類 型 的 匿 名 成 員 , 這 樣 就 可 以 通 過 簡 單 的 點 運 算 符 x.f來 訪 問 匿 名 成 員 鏈 中 嵌 套 的 x.d.e.f成 員 。 < / p >
< p > 考 慮 一 個 二 維 的 繪 圖 程 序 , 提 供 了 一 個 各 種 圖 形 的 庫 , 例 如 矩 形 、 橢 圓 形 、 星 形 和 輪 形 等 幾 何 形 狀 。 這 里 是 其 中 兩 個 的 定 義 : < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > type< / span > Circle < span class = "hljs-keyword" > struct< / span > {
X, Y, Radius < span class = "hljs-typename" > int< / span >
}
< span class = "hljs-keyword" > type< / span > Wheel < span class = "hljs-keyword" > struct< / span > {
X, Y, Radius, Spokes < span class = "hljs-typename" > int< / span >
}
< / code > < / pre >
< p > 一 個 Circle代 表 的 圓 形 類 型 包 含 了 標 準 圓 心 的 X和 Y坐 標 信 息 , 和 一 個 Radius表 示 的 半 徑 信 息 。 一 個 Wheel輪 形 除 了 包 含 Circle類 型 所 有 的 全 部 成 員 外 , 還 增 加 了 Spokes表 示 徑 向 輻 條 的 數 量 。 我 們 可 以 這 樣 創 建 一 個 wheel變 量 : < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > var< / span > w Wheel
w.X = < span class = "hljs-number" > 8< / span >
w.Y = < span class = "hljs-number" > 8< / span >
w.Radius = < span class = "hljs-number" > 5< / span >
w.Spokes = < span class = "hljs-number" > 20< / span >
< / code > < / pre >
< p > 隨 着 庫 中 幾 何 形 狀 數 量 的 增 多 , 我 們 一 定 會 註 意 到 它 們 之 間 的 相 似 和 重 複 之 處 , 所 以 我 們 可 能 爲 了 便 於 維 護 而 將 相 同 的 屬 性 獨 立 出 來 : < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > type< / span > Point < span class = "hljs-keyword" > struct< / span > {
X, Y < span class = "hljs-typename" > int< / span >
}
< span class = "hljs-keyword" > type< / span > Circle < span class = "hljs-keyword" > struct< / span > {
Center Point
Radius < span class = "hljs-typename" > int< / span >
}
< span class = "hljs-keyword" > type< / span > Wheel < span class = "hljs-keyword" > struct< / span > {
Circle Circle
Spokes < span class = "hljs-typename" > int< / span >
}
< / code > < / pre >
< p > 這 樣 改 動 之 後 結 構 體 類 型 變 的 清 晰 了 , 但 是 這 種 脩 改 同 時 也 導 致 了 訪 問 每 個 成 員 變 得 繁 瑣 : < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > var< / span > w Wheel
w.Circle.Center.X = < span class = "hljs-number" > 8< / span >
w.Circle.Center.Y = < span class = "hljs-number" > 8< / span >
w.Circle.Radius = < span class = "hljs-number" > 5< / span >
w.Spokes = < span class = "hljs-number" > 20< / span >
< / code > < / pre >
< p > Go語 言 有 一 個 特 性 讓 我 們 隻 聲 明 一 個 成 員 對 應 的 數 據 類 型 而 不 指 名 成 員 的 名 字 ; 這 類 成 員 就 叫 匿 名 成 員 。 匿 名 成 員 的 數 據 類 型 必 鬚 是 命 名 的 類 型 或 指 向 一 個 命 名 的 類 型 的 指 針 。 下 面 的 代 碼 中 , Circle和 Wheel各 自 都 有 一 個 匿 名 成 員 。 我 們 可 以 説 Point類 型 被 嵌 入 了 Circle結 構 體 , 同 時 Circle類 型 被 嵌 入 了 Wheel結 構 體 。 < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > type< / span > Circle < span class = "hljs-keyword" > struct< / span > {
Point
Radius < span class = "hljs-typename" > int< / span >
}
< span class = "hljs-keyword" > type< / span > Wheel < span class = "hljs-keyword" > struct< / span > {
Circle
Spokes < span class = "hljs-typename" > int< / span >
}
< / code > < / pre >
< p > 得 意 於 匿 名 嵌 入 的 特 性 , 我 們 可 以 直 接 訪 問 葉 子 屬 性 而 不 需 要 給 出 完 整 的 路 徑 : < / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > var< / span > w Wheel
w.X = < span class = "hljs-number" > 8< / span > < span class = "hljs-comment" > // equivalent to w.Circle.Point.X = 8< / span >
w.Y = < span class = "hljs-number" > 8< / span > < span class = "hljs-comment" > // equivalent to w.Circle.Point.Y = 8< / span >
w.Radius = < span class = "hljs-number" > 5< / span > < span class = "hljs-comment" > // equivalent to w.Circle.Radius = 5< / span >
w.Spokes = < span class = "hljs-number" > 20< / span >
< / code > < / pre >
< p > 在 右 邊 的 註 釋 中 給 出 的 顯 式 形 式 訪 問 這 些 葉 子 成 員 的 語 法 依 然 有 效 , 因 此 匿 名 成 員 併 不 是 眞 的 無 法 訪 問 了 。 其 中 匿 名 成 員 Circle和 Point都 有 自 己 的 名 字 — — 就 是 命 名 的 類 型 名 字 — — 但 是 這 些 名 字 在 點 操 作 符 中 是 可 選 的 。 我 們 在 訪 問 子 成 員 的 時 候 可 以 忽 略 任 何 匿 名 成 員 部 分 。 < / p >
< p > 不 幸 的 是 , 結 構 體 字 面 值 併 沒 有 簡 短 表 示 匿 名 成 員 的 語 法 , 因 此 下 面 的 語 句 都 不 能 編 譯 通 過 : < / p >
< pre > < code class = "lang-Go" > w = Wheel{< span class = "hljs-number" > 8< / span > , < span class = "hljs-number" > 8< / span > , < span class = "hljs-number" > 5< / span > , < span class = "hljs-number" > 20< / span > } < span class = "hljs-comment" > // compile error: unknown fields< / span >
w = Wheel{X: < span class = "hljs-number" > 8< / span > , Y: < span class = "hljs-number" > 8< / span > , Radius: < span class = "hljs-number" > 5< / span > , Spokes: < span class = "hljs-number" > 20< / span > } < span class = "hljs-comment" > // compile error: unknown fields< / span >
< / code > < / pre >
< p > 結 構 體 字 面 值 必 鬚 遵 循 形 狀 類 型 聲 明 時 的 結 構 , 所 以 我 們 隻 能 用 下 面 的 兩 種 語 法 , 它 們 彼 此 是 等 價 的 : < / p >
< pre > < code class = "lang-Go" > gopl.io/ch4/embed
w = Wheel{Circle{Point{< span class = "hljs-number" > 8< / span > , < span class = "hljs-number" > 8< / span > }, < span class = "hljs-number" > 5< / span > }, < span class = "hljs-number" > 20< / span > }
w = Wheel{
Circle: Circle{
Point: Point{X: < span class = "hljs-number" > 8< / span > , Y: < span class = "hljs-number" > 8< / span > },
Radius: < span class = "hljs-number" > 5< / span > ,
},
Spokes: < span class = "hljs-number" > 20< / span > , < span class = "hljs-comment" > // < span class = "hljs-doctag" > NOTE:< / span > trailing comma necessary here (and at Radius)< / span >
}
fmt.Printf(< span class = "hljs-string" > " %#v\n" < / span > , w)
< span class = "hljs-comment" > // Output:< / span >
< span class = "hljs-comment" > // Wheel{Circle:Circle{Point:Point{X:8, Y:8}, Radius:5}, Spokes:20}< / span >
w.X = < span class = "hljs-number" > 42< / span >
fmt.Printf(< span class = "hljs-string" > " %#v\n" < / span > , w)
< span class = "hljs-comment" > // Output:< / span >
< span class = "hljs-comment" > // Wheel{Circle:Circle{Point:Point{X:42, Y:8}, Radius:5}, Spokes:20}< / span >
< / code > < / pre >
< p > 需 要 註 意 的 是 Printf函 數 中 %v參 數 包 含 的 #副 詞 , 它 表 示 用 和 Go語 言 類 似 的 語 法 打 印 值 。 對 於 結 構 體 類 型 來 説 , 將 包 含 每 個 成 員 的 名 字 。 < / p >
< p > 因 爲 匿 名 成 員 也 有 一 個 隱 式 的 名 字 , 因 此 不 能 同 時 包 含 兩 個 類 型 相 同 的 匿 名 成 員 , 這 會 導 致 名 字 衝 突 。 同 時 , 因 爲 成 員 的 名 字 是 由 其 類 型 隱 式 地 決 定 的 , 所 有 匿 名 成 員 也 有 可 見 性 的 規 則 約 束 。 在 上 面 的 例 子 中 , Point和 Circle匿 名 成 員 都 是 導 出 的 。 卽 使 它 們 不 導 出 ( 比 如 改 成 小 寫 字 母 開 頭 的 point和 circle) , 我 們 依 然 可 以 用 簡 短 形 式 訪 問 匿 名 成 員 嵌 套 的 成 員 < / p >
< pre > < code class = "lang-Go" > w.X = < span class = "hljs-number" > 8< / span > < span class = "hljs-comment" > // equivalent to w.circle.point.X = 8< / span >
< / code > < / pre >
< p > 但 是 在 包 外 部 , 因 爲 circle和 point沒 有 導 出 不 能 訪 問 它 們 的 成 員 , 因 此 簡 短 語 法 也 是 禁 止 的 。 < / p >
< p > 到 目 前 未 知 , 我 們 看 到 匿 名 成 員 特 性 隻 是 對 訪 問 嵌 套 成 員 的 點 運 算 符 提 供 了 簡 短 的 語 法 醣 。 稍 後 , 我 們 將 會 看 到 匿 名 成 員 併 不 要 求 是 結 構 體 類 型 ; 其 實 任 何 命 令 的 類 型 都 可 以 作 爲 結 構 體 的 匿 名 成 員 。 但 是 爲 什 麽 要 嵌 入 一 個 沒 有 任 何 子 成 員 類 型 的 匿 名 成 員 類 型 呢 ? < / p >
< p > 答 案 是 匿 名 類 型 的 方 法 集 。 簡 短 的 點 運 算 符 語 法 可 以 用 於 選 擇 匿 名 成 員 嵌 套 的 成 員 , 也 可 以 用 於 訪 問 它 們 的 方 法 。 實 際 上 , 外 層 的 結 構 體 不 僅 僅 是 獲 得 了 匿 名 成 員 類 型 的 所 有 成 員 , 而 且 也 獲 得 了 該 類 型 導 出 的 全 部 的 方 法 。 這 個 機 製 可 以 用 於 將 一 個 有 簡 單 行 爲 的 對 象 組 合 成 有 複 雜 行 爲 的 對 象 。 組 合 是 Go語 言 中 面 向 對 象 編 程 的 覈 心 , 我 們 將 在 6.3節 中 專 門 討 論 。 < / p >
2015-12-09 07:57:17 +00:00
< / section >
< / div >
< / div >
< / div >
2015-12-31 08:20:27 +00:00
< a href = "../ch4/ch4-03.html" class = "navigation navigation-prev " aria-label = "Previous page: Map" > < i class = "fa fa-angle-left" > < / i > < / a >
2015-12-09 07:57:17 +00:00
< a href = "../ch4/ch4-05.html" class = "navigation navigation-next " aria-label = "Next page: JSON" > < i class = "fa fa-angle-right" > < / i > < / a >
< / div >
< / div >
< script src = "../gitbook/app.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) {
2015-12-28 08:08:26 +00:00
var config = {"katex":{},"highlight":{},"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}};
2015-12-09 07:57:17 +00:00
gitbook.start(config);
});
< / script >
< / body >
< / html >