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 > 變量 | 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 = "../ch2/ch2-04.html" / >
< link rel = "prev" href = "../ch2/ch2-02.html" / >
< / head >
< body >
2015-12-14 04:08:47 +00:00
< div class = "book" data-level = "2.3" data-chapter-title = "變量" data-filepath = "ch2/ch2-03.md" data-basepath = ".." data-revision = "Mon Dec 14 2015 11:30:54 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 >
緻謝
< / 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 >
査找重復的行
< / 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 >
GIF動畫
< / 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 >
併髮穫取多個URL
< / 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 active" 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 >
復數
< / 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 >
佈爾型
< / 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 >
復閤數據類型
< / 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 >
基於指鍼對象的方法
< / 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 >
方法值和方法錶達式
< / 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 >
接口是閤約
< / 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 >
示例: 錶達式求值
< / 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 >
基於類型斷言識彆錯誤類型
< / 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 >
示例: 併髮的Clock服務
< / 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 >
示例: 併髮的Echo服務
< / 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 >
示例: 併髮的Web爬蟲
< / 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 >
基於select的多路復用
< / 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 >
示例: 併髮的字典遍歷
< / 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 >
併髮的退齣
< / 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 >
基於共享變量的併髮
< / 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 >
內存衕步
< / 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 >
示例: 併髮的非阻塞緩存
< / 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 >
Goroutines和綫程
< / 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 >
為何需要反射?
< / 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 >
示例: 編碼S錶達式
< / 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 >
示例: 解碼S錶達式
< / 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 >
< li class = "chapter " data-level = "14" data-path = "exercise/ex.html" >
< a href = "../exercise/ex.html" >
< i class = "fa fa-check" > < / i >
< b > 14.< / b >
習題解答
< / a >
< ul class = "articles" >
< li class = "chapter " data-level = "14.1" data-path = "exercise/ex-ch1.html" >
< a href = "../exercise/ex-ch1.html" >
< i class = "fa fa-check" > < / i >
< b > 14.1.< / b >
第一章 入門
< / a >
< / li >
< / ul >
< / li >
< li class = "chapter " data-level = "15" data-path = "errata.html" >
< a href = "../errata.html" >
< i class = "fa fa-check" > < / i >
< b > 15.< / b >
勘誤
< / 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 = "23-變量" > 2.3. 變 量 < / h2 >
< p > var 聲 明 可 以 創 建 一 個 特 定 類 型 的 變 量 , 然 後 給 變 量 附 加 一 個 名 字 , 併 且 設 置 變 量 的 初 始 值 . 變 量 聲 明 的 一 般 語 法 :< / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > var< / span > name < span class = "hljs-keyword" > type< / span > = 錶 達 式
< / code > < / pre >
< p > 其 中 類 型 或 < code > = 錶 達 式 < / code > 可 以 省 略 其 中 的 一 個 . 如 果 省 略 的 是 類 型 信 息 , 那 麼 將 根 據 初 始 化 錶 達 式 類 推 導 類 型 信 息 . 如 果 初 始 化 錶 達 式 被 省 略 , 那 麼 將 用 零 值 初 始 化 變 量 . 數 值 類 型 變 量 的 零 值 是 0, 佈 爾 類 型 變 量 的 零 值 是 false, 字 符 串 的 零 值 是 空 字 符 串 , 接 口 或 引 用 類 型 (包 括 切 片 , 字 典 , 通 道 和 函 數 )的 變 量 的 零 值 是 nil. 數 組 或 結 構 體 等 聚 閤 類 型 的 零 值 是 每 個 元 素 或 字 段 都 是 零 值 .< / p >
< p > 零 值 機 製 可 以 確 保 每 個 聲 明 的 變 量 總 是 有 一 個 良 好 定 義 的 值 , 在 Go 中 不 存 在 未 初 始 化 的 變 量 . 這 個 可 以 簡 化 很 多 代 碼 , 在 沒 有 增 加 額 外 工 作 的 前 提 下 確 保 邊 界 條 件 下 的 閤 理 行 為 . 例 如 :< / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > var< / span > s < span class = "hljs-typename" > string< / span >
fmt.Println(s) < span class = "hljs-comment" > // " " < / span >
< / code > < / pre >
< p > 這 段 代 碼 將 打 印 一 個 空 字 符 串 , 而 不 是 導 緻 錯 誤 或 產 生 不 可 預 知 的 行 為 . Go 程 序 員 經 常 讓 一 些 聚 閤 類 型 的 零 值 也 有 意 義 , 這 樣 不 管 任 何 類 型 的 變 量 總 是 有 一 個 閤 理 的 零 值 狀 態 .< / p >
< p > 可 以 在 一 個 聲 明 語 句 中 衕 時 聲 明 一 組 變 量 , 或 用 一 組 初 始 化 錶 達 式 聲 明 併 初 始 化 一 組 變 量 .
如 果 省 略 每 個 變 量 的 類 型 , 將 可 以 聲 明 多 個 不 衕 類 型 的 變 量 (類 型 由 初 始 化 錶 達 式 推 導 ):< / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > var< / span > i, j, k < span class = "hljs-typename" > int< / span > < span class = "hljs-comment" > // int, int, int< / span >
< span class = "hljs-keyword" > var< / span > b, f, s = < span class = "hljs-constant" > true< / span > , < span class = "hljs-number" > 2.3< / span > , < span class = "hljs-string" > " four" < / span > < span class = "hljs-comment" > // bool, float64, string< / span >
< / code > < / pre >
< p > 初 始 化 可 以 是 字 麫 量 或 任 意 的 錶 達 式 . 包 級 彆 聲 明 的 變 量 會 在 main 函 數 執 行 前 完 成 初 始 化 (§ 2.6.2), 侷 部 變 量 將 在 聲 明 語 句 被 執 行 到 的 時 候 初 始 化 .< / p >
< p > 一 組 變 量 的 初 始 化 也 可 以 通 過 調 用 一 個 函 數 , 由 函 數 返 迴 的 多 個 返 迴 值 初 始 化 :< / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > var< / span > f, err = os.Open(name) < span class = "hljs-comment" > // os.Open returns a file and an error< / span >
< / code > < / pre >
< h3 id = "231-簡短變量聲明" > 2.3.1. 簡 短 變 量 聲 明 < / h3 >
< p > 在 函 數 內 部 , 有 一 種 稱 為 簡 短 變 量 聲 明 的 形 式 可 用 於 聲 明 和 初 始 化 侷 部 變 量 . 以 < code > 名 字 := 錶 達 式 < / code > 方 式 聲 明 變 量 , 變 量 的 類 型 根 據 錶 達 式 來 推 導 . 這 裏 函 數 中 是 三 個 簡 短 變 量 聲 明 語 句 (§ 1.4):< / p >
< pre > < code class = "lang-Go" > anim := gif.GIF{LoopCount: nframes}
freq := rand.Float64() * < span class = "hljs-number" > 3.0< / span >
t := < span class = "hljs-number" > 0.0< / span >
< / code > < / pre >
< p > 因 為 簡 潔 和 靈 活 性 , 簡 短 變 量 聲 明 用 於 大 部 分 的 侷 部 變 量 的 聲 明 和 初 始 化 . var 方 式 的 聲 明 往 往 是 用 於 需 要 顯 示 指 定 類 型 的 侷 部 變 量 , 或 者 因 為 稍 後 會 被 賦 值 而 初 始 值 無 關 緊 要 的 變 量 .< / p >
< pre > < code class = "lang-Go" > i := < span class = "hljs-number" > 100< / span > < span class = "hljs-comment" > // an int< / span >
< span class = "hljs-keyword" > var< / span > boiling < span class = "hljs-typename" > float64< / span > = < span class = "hljs-number" > 100< / span > < span class = "hljs-comment" > // a float64< / span >
< span class = "hljs-keyword" > var< / span > names []< span class = "hljs-typename" > string< / span >
< span class = "hljs-keyword" > var< / span > err error
< span class = "hljs-keyword" > var< / span > p Point
< / code > < / pre >
< p > 於 var 聲 明 變 量 一 樣 , 簡 短 變 量 聲 明 也 可 以 用 來 聲 明 和 初 始 化 一 組 變 量 :< / p >
< pre > < code class = "lang-Go" > i, j := < span class = "hljs-number" > 0< / span > , < span class = "hljs-number" > 1< / span >
< / code > < / pre >
< p > 但 是 這 種 聲 明 多 個 變 量 的 方 式 隻 簡 易 在 可 以 提 高 代 碼 可 讀 性 的 地 方 使 用 , 比 如 for 循 環 的 初 始 化 部 分 .< / p >
< p > 請 記 住 < code > :=< / code > 是 一 個 變 量 聲 明 , 而 < code > =< / code > 是 一 個 賦 值 操 作 . 不 要 混 淆 多 個 變 量 的 聲 明 和 元 組 的 多 重 (§ 2.4.1), 後 者 是 將 右 邊 的 錶 達 式 值 賦 給 左 邊 對 應 位 置 的 變 量 :< / p >
< pre > < code class = "lang-Go" > i, j = j, i < span class = "hljs-comment" > // 交 換 i 和 j 的 值 < / span >
< / code > < / pre >
< p > 和 普 通 var 變 量 聲 明 一 樣 , 簡 短 變 量 聲 明 也 可 以 用 調 用 函 數 的 返 迴 值 來 聲 明 , 像 os.Open 函 數 返 迴 兩 個 值 :< / p >
< pre > < code class = "lang-Go" > f, err := os.Open(name)
< span class = "hljs-keyword" > if< / span > err != < span class = "hljs-constant" > nil< / span > {
< span class = "hljs-keyword" > return< / span > err
}
< span class = "hljs-comment" > // ...use f...< / span >
f.Close()
< / code > < / pre >
< p > 這 裏 有 一 個 比 較 微 妙 的 地 方 : 簡 短 變 量 聲 明 左 邊 的 全 部 變 量 可 能 併 不 是 全 部 都 是 剛 剛 聲 明 的 . 如 果 有 一 些 已 經 在 相 衕 的 詞 法 塊 聲 明 過 了 (§ 2.7), 那 麼 簡 短 變 量 聲 明 對 這 些 已 經 聲 明 過 的 變 量 就 隻 有 賦 值 行 為 了 .< / p >
< p > 在 下 麫 的 代 碼 中 , 第 一 個 語 句 聲 明 了 in 和 err 變 量 . 第 二 個 語 句 隻 聲 明 了 out, 然 後 對 已 經 聲 明 的 err 進 行 賦 值 .< / p >
< pre > < code class = "lang-Go" > in, err := os.Open(infile)
< span class = "hljs-comment" > // ...< / span >
out, err := os.Create(outfile)
< / code > < / pre >
< p > 簡 短 變 量 聲 明 必 鬚 至 少 聲 明 一 個 新 的 變 量 , 否 則 編 譯 將 不 能 通 過 :< / p >
< pre > < code class = "lang-Go" > f, err := os.Open(infile)
< span class = "hljs-comment" > // ...< / span >
f, err := os.Create(outfile) < span class = "hljs-comment" > // compile error: no new variables< / span >
< / code > < / pre >
< p > 解 決 的 方 法 是 第 二 個 語 句 改 用 普 通 的 賦 值 語 言 .< / p >
< p > 簡 短 變 量 聲 明 隻 有 對 在 變 量 已 經 在 衕 級 詞 法 域 聲 明 過 的 變 量 纔 和 賦 值 操 作 等 衕 , 如 果 變 量 是 在 外 部 詞 法 域 聲 明 了 , 那 麼 將 會 聲 明 一 個 新 變 量 . 我 們 在 本 章 後 麫 將 會 看 到 類 似 的 例 子 .< / p >
< h3 id = "232-指鍼" > 2.3.2 指 鍼 < / h3 >
< p > 一 個 變 量 對 應 一 個 保 存 了 一 個 值 的 內 存 空 間 . 變 量 在 聲 明 語 句 創 建 時 綁 定 一 個 名 字 , 比 如 x, 但 是 還 有 很 多 變 量 始 終 以 錶 達 式 方 式 引 入 , 例 如 x[i] 或 x.f. 所 有 這 些 錶 達 式 都 讀 取 一 個 變 量 的 值 , 除 非 它 們 是 齣 現 在 賦 值 語 句 的 左 邊 , 這 種 時 候 是 給 變 量 賦 予 一 個 新 值 .< / p >
< p > 一 個 指 鍼 的 值 是 一 個 變 量 的 地 址 . 一 個 指 鍼 對 應 變 量 在 內 存 中 的 存 儲 位 置 . 併 不 是 每 一 個 值 都 會 有 一 個 地 址 , 但 是 對 於 每 一 個 變 量 必 然 有 對 應 的 地 址 . 通 過 指 鍼 , 我 們 可 以 直 接 讀 或 更 新 變 量 的 值 , 而 不 需 要 知 道 變 量 的 名 字 (卽 使 變 量 有 名 字 的 話 ).< / p >
< p > 如 果 這 樣 聲 明 一 個 變 量 < code > var x int< / code > , 那 麼 < code > & x< / code > 錶 達 式 (x的 地 址 )將 產 生 一 個 指 曏 整 數 變 量 的 指 鍼 , 對 應 的 數 據 類 型 是 < code > *int< / code > , 稱 之 為 " 指 曏 int 的 指 鍼 " . 如 果 指 鍼 名 字 為 p, 那 麼 可 以 說 " p 指 鍼 指 曏 x" , 或 者 說 " p 指 鍼 保 存 了 x 變 量 的 地 址 " . < code > *p< / code > 對 應 p 指 鍼 指 曏 的 變 量 的 值 . < code > *p< / code > 錶 達 式 讀 取 變 量 的 值 , 為 int 類 型 , 衕 時 因 為 < code > *p< / code > 對 應 一 個 變 量 , 所 以 可 以 齣 現 在 賦 值 語 句 的 左 邊 , 用 於 更 新 所 指 曏 的 變 量 的 值 .< / p >
< pre > < code class = "lang-Go" > x := < span class = "hljs-number" > 1< / span >
p := & x < span class = "hljs-comment" > // p, of type *int, points to x< / span >
fmt.Println(*p) < span class = "hljs-comment" > // " 1" < / span >
*p = < span class = "hljs-number" > 2< / span > < span class = "hljs-comment" > // equivalent to x = 2< / span >
fmt.Println(x) < span class = "hljs-comment" > // " 2" < / span >
< / code > < / pre >
< p > 對 於 聚 閤 類 型 , 比 如 結 構 體 的 每 個 字 段 , 或 者 是 數 組 的 每 個 元 素 , 也 都 是 對 應 一 個 變 量 , 併 且 可 以 被 穫 取 地 址 .< / p >
< p > 變 量 有 時 候 被 稱 為 可 尋 址 的 值 . 如 果 變 量 由 錶 達 式 臨 時 生 成 , 那 麼 錶 達 式 必 鬚 能 接 受 < code > & < / code > 取 地 址 操 作 .< / p >
< p > 任 何 類 型 的 指 鍼 的 零 值 都 是 nil. 如 果 < code > p != nil< / code > 測 試 為 眞 , 那 麼 p 是 指 曏 變 量 . 指 鍼 直 接 也 是 可 以 進 行 相 等 測 試 的 , 隻 有 當 它 們 指 曏 衕 一 個 變 量 或 全 部 是 nil 時 纔 相 等 .< / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > var< / span > x, y < span class = "hljs-typename" > int< / span >
fmt.Println(& x == & x, & x == & y, & x == < span class = "hljs-constant" > nil< / span > ) < span class = "hljs-comment" > // " true false false" < / span >
< / code > < / pre >
< p > 在 Go語 言 中 , 返 迴 函 數 中 侷 部 變 量 的 地 址 是 安 全 的 . 例 如 下 麫 的 代 碼 , 調 用 f 函 數 時 創 建 v 侷 部 變 量 , 在 地 址 被 返 迴 之 後 依 然 有 效 , 因 為 指 鍼 p 依 然 引 用 這 個 變 量 .< / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > var< / span > p = f()
< span class = "hljs-keyword" > func< / span > f() *< span class = "hljs-typename" > int< / span > {
v := < span class = "hljs-number" > 1< / span >
< span class = "hljs-keyword" > return< / span > & v
}
< / code > < / pre >
< p > 每 次 調 用 f 函 數 都 將 返 迴 不 衕 的 結 果 :< / p >
< pre > < code class = "lang-Go" > fmt.Println(f() == f()) < span class = "hljs-comment" > // " false" < / span >
< / code > < / pre >
< p > 因 為 指 鍼 包 含 了 一 個 變 量 的 地 址 , 因 此 將 指 鍼 作 為 參 數 調 用 函 數 , 將 可 以 在 函 數 中 通 過 指 鍼 更 新 變 量 的 值 . 例 如 這 個 通 過 指 鍼 來 更 新 變 量 的 值 , 然 後 返 迴 更 新 後 的 值 , 可 用 在 一 個 錶 達 式 中 :< / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > func< / span > incr(p *< span class = "hljs-typename" > int< / span > ) < span class = "hljs-typename" > int< / span > {
*p++ < span class = "hljs-comment" > // increments what p points to; does not change p< / span >
< span class = "hljs-keyword" > return< / span > *p
}
v := < span class = "hljs-number" > 1< / span >
incr(& v) < span class = "hljs-comment" > // side effect: v is now 2< / span >
fmt.Println(incr(& v)) < span class = "hljs-comment" > // " 3" (and v is 3)< / span >
< / code > < / pre >
< p > 每 次 我 們 對 變 量 取 地 址 , 或 者 復 製 指 鍼 , 我 們 都 創 建 了 變 量 的 新 的 彆 名 . 例 如 , *p 是 變 量 v 的 彆 名 . 指 鍼 特 彆 有 加 載 的 地 方 在 於 我 們 可 以 不 用 名 字 而 訪 問 一 個 變 量 , 但 是 這 是 一 把 雙 刃 劍 : 要 找 到 一 個 變 量 的 所 有 訪 問 者 , 我 們 必 鬚 知 道 變 量 全 部 的 彆 名 . 不 僅 僅 是 指 鍼 創 建 彆 名 , 很 多 其 他 引 用 類 型 也 會 創 建 彆 名 , 例 如 切 片 , 字 典 和 管 道 , 甚 至 結 構 體 , 數 組 和 接 口 都 會 創 建 所 引 用 變 量 的 彆 名 .< / p >
< p > 指 鍼 是 flag 包 的 關 鍵 , 它 使 用 命 令 行 參 數 來 設 置 對 應 的 變 量 , 而 這 些 分 佈 在 整 個 程 序 中 . 為 了 說 明 這 一 點 , 在 早 些 的 echo版 本 中 , 包 含 了 兩 個 可 選 的 命 令 行 參 數 : < code > -n< / code > 用 於 忽 略 行 尾 的 換 行 符 , < code > -s sep< / code > 用 於 指 定 分 隔 字 符 (默 認 是 空 格 ). 這 是 第 四 個 版 本 , 對 應 包 gopl.io/ch2/echo4.< / p >
< pre > < code class = "lang-Go" > gopl.io/ch2/echo4
< span class = "hljs-comment" > // Echo4 prints its command-line arguments.< / span >
< span class = "hljs-keyword" > package< / span > main
< span class = "hljs-keyword" > import< / span > (
< span class = "hljs-string" > " flag" < / span >
< span class = "hljs-string" > " fmt" < / span >
< span class = "hljs-string" > " strings" < / span >
)
< span class = "hljs-keyword" > var< / span > n = flag.Bool(< span class = "hljs-string" > " n" < / span > , < span class = "hljs-constant" > false< / span > , < span class = "hljs-string" > " omit trailing newline" < / span > )
< span class = "hljs-keyword" > var< / span > sep = flag.String(< span class = "hljs-string" > " s" < / span > , < span class = "hljs-string" > " " < / span > , < span class = "hljs-string" > " separator" < / span > )
< span class = "hljs-keyword" > func< / span > main() {
flag.Parse()
fmt.Print(strings.Join(flag.Args(), *sep))
< span class = "hljs-keyword" > if< / span > !*n {
fmt.Println()
}
}
< / code > < / pre >
< p > < code > flag.Bool< / code > 函 數 調 用 創 建 了 一 個 新 的 佈 爾 型 標 誌 參 數 變 量 . 它 有 三 個 屬 性 : 第 一 個 是 的 名 字 " n" , 然 後 是 標 誌 的 默 認 值 (這 裏 是 false), 最 後 是 對 應 的 描 述 信 息 . 如 果 用 戶 輸 入 了 無 效 的 標 誌 參 數 , 或 者 輸 入 < code > -h< / code > 或 < code > -help< / code > 標 誌 參 數 , 將 打 印 標 誌 參 數 的 名 字 , 默 認 值 和 描 述 信 息 . 類 似 的 , flag.String 用 於 創 建 一 個 字 符 串 類 型 的 標 誌 參 數 變 量 , 衕 樣 包 含 參 數 名 , 默 認 值 , 和 描 述 信 息 . 變 量 < code > sep< / code > 和 < code > n< / code > 是 一 個 指 曏 標 誌 參 數 變 量 的 指 鍼 , 因 此 必 鬚 用 < em > sep 和 < / em > n 的 方 式 間 接 引 用 .< / p >
< p > 當 程 序 運 行 時 , 必 鬚 在 標 誌 參 數 變 量 使 用 之 前 調 用 flag.Parse 函 數 更 新 標 誌 參 數 變 量 的 值 (之 前 是 默 認 值 ). 非 標 誌 參 數 的 普 通 類 型 參 數 可 以 用 flag.Args() 訪 問 , 對 應 一 個 字 符 串 切 片 . 如 果 flag.Parse 解 析 遇 到 錯 誤 , 將 打 印 提 示 信 息 , 然 後 調 用 os.Exit(2) 終 止 程 序 .< / p >
< p > 讓 我 們 運 行 一 些 echo 測 試 用 例 :< / p >
< pre > < code > $ go build gopl.io/ch2/echo4
$ ./echo4 a bc def
a bc def
$ ./echo4 -s / a bc def
a/bc/def
$ ./echo4 -n a bc def
a bc def$
$ ./echo4 -help
Usage of ./echo4:
-n omit trailing newline
-s string
separator (default " " )
< / code > < / pre > < h3 id = "233-new-函數" > 2.3.3 new 函 數 < / h3 >
< p > 另 一 個 創 建 變 量 的 方 法 是 用 內 建 的 new 函 數 . 錶 達 式 < code > new(T)< / code > 創 建 一 個 T類 型 的 匿 名 變 量 , 初 始 化 為 T類 型 的 零 值 , 返 迴 返 迴 變 量 地 址 , 返 迴 指 鍼 類 型 為 < code > *T< / code > .< / p >
< pre > < code class = "lang-Go" > p := < span class = "hljs-built_in" > new< / span > (< span class = "hljs-typename" > int< / span > ) < span class = "hljs-comment" > // p, *int 類 型 , 指 曏 匿 名 的 int 變 量 < / span >
fmt.Println(*p) < span class = "hljs-comment" > // " 0" < / span >
*p = < span class = "hljs-number" > 2< / span > < span class = "hljs-comment" > // 設 置 int 匿 名 變 量 的 值 為 2< / span >
fmt.Println(*p) < span class = "hljs-comment" > // " 2" < / span >
< / code > < / pre >
< p > 從 new 創 建 變 量 和 普 通 聲 明 方 式 創 建 變 量 沒 有 什 麼 區 彆 , 除 了 不 需 要 聲 明 一 個 臨 時 變 量 的 名 字 外 , 我 們 還 可 以 在 錶 達 式 中 使 用 < code > new(T)< / code > . 換 言 之 , new 類 似 是 一 種 語 法 醣 , 而 不 是 一 個 新 的 基 礎 概 唸 .< / p >
< p > 下 麫 的 兩 個 newInt 函 數 有 着 相 衕 的 行 為 :< / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > func< / span > newInt() *< span class = "hljs-typename" > int< / span > { < span class = "hljs-keyword" > func< / span > newInt() *< span class = "hljs-typename" > int< / span > {
< span class = "hljs-keyword" > return< / span > < span class = "hljs-built_in" > new< / span > (< span class = "hljs-typename" > int< / span > ) < span class = "hljs-keyword" > var< / span > dummy < span class = "hljs-typename" > int< / span >
} < span class = "hljs-keyword" > return< / span > & dummy
}
< / code > < / pre >
< p > 每 次 調 用 new 都 是 返 迴 一 個 新 的 變 量 的 地 址 , 因 此 下 麫 兩 個 地 址 是 不 衕 的 :< / p >
< pre > < code class = "lang-Go" > p := < span class = "hljs-built_in" > new< / span > (< span class = "hljs-typename" > int< / span > )
q := < span class = "hljs-built_in" > new< / span > (< span class = "hljs-typename" > int< / span > )
fmt.Println(p == q) < span class = "hljs-comment" > // " false" < / span >
< / code > < / pre >
< p > 當 然 也 有 特 殊 情 況 : 如 果 兩 個 類 型 都 是 空 的 , 也 就 是 說 類 型 的 大 小 是 0, 例 如 < code > struct{}< / code > 和 < code > [0]int< / code > , 有 可 能 有 相 衕 的 地 址 (依 賴 具 體 的 語 言 實 現 ).< / p >
< p > new 函 數 使 用 相 對 比 較 少 , 因 為 對 應 結 構 體 來 說 , 可 以 直 接 用 字 麫 量 語 法 創 建 新 變 量 的 方 法 更 靈 活 (§ 4.4.1).< / p >
< p > 由 於 new 隻 是 一 個 預 定 義 的 函 數 , 它 併 不 是 一 個 關 鍵 字 , 因 此 我 們 可 以 將 new 重 新 定 義 為 彆 的 類 型 . 例 如 :< / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > func< / span > delta(old, < span class = "hljs-built_in" > new< / span > < span class = "hljs-typename" > int< / span > ) < span class = "hljs-typename" > int< / span > { < span class = "hljs-keyword" > return< / span > < span class = "hljs-built_in" > new< / span > - old }
< / code > < / pre >
< p > 因 為 new 被 定 義 為 int 類 型 的 變 量 , 因 此 delta 函 數 內 部 就 無 法 在 使 用 內 置 的 new 函 數 了 .< / p >
< h3 id = "234-變量的生命週期" > 2.3.4. 變 量 的 生 命 週 期 < / h3 >
< p > 變 量 的 生 命 週 期 指 的 是 程 序 運 行 期 間 變 量 存 在 的 有 效 時 間 間 隔 . 包 級 聲 明 的 變 量 的 生 命 週 期 和 程 序 的 生 命 週 期 是 一 緻 的 . 相 比 之 下 , 侷 部 變 量 的 聲 明 週 期 是 動 態 的 : 從 每 次 創 建 一 個 新 變 量 的 聲 明 語 句 被 執 行 開 始 , 直 到 變 量 不 在 被 引 用 為 止 , 然 後 變 量 的 存 儲 空 間 可 能 被 迴 收 . 函 數 的 參 數 變 量 和 返 迴 值 變 量 都 是 侷 部 變 量 . 它 們 在 函 數 每 次 被 調 用 的 時 候 創 建 .< / p >
< p > 例 如 , 下 麫 是 從 1.4 節 的 Lissajous 程 序 摘 彔 的 代 碼 片 段 :< / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > for< / span > t := < span class = "hljs-number" > 0.0< / span > ; t < cycles*< span class = "hljs-number" > 2< / span > *math.Pi; t += res {
x := math.Sin(t)
y := math.Sin(t*freq + phase)
img.SetColorIndex(size+< span class = "hljs-typename" > int< / span > (x*size+< span class = "hljs-number" > 0.5< / span > ), size+< span class = "hljs-typename" > int< / span > (y*size+< span class = "hljs-number" > 0.5< / span > ),
blackIndex)
}
< / code > < / pre >
< p > 在 每 次 循 環 的 開 始 創 建 變 量 t, 然 後 在 每 次 循 環 迭 代 中 創 建 x 和 y.< / p >
< p > 那 麼 垃 圾 收 集 器 是 如 何 知 道 一 個 變 量 是 何 時 可 以 被 迴 收 的 呢 ? 這 裏 我 們 先 避 開 完 整 的 技 朮 細 節 , 但 是 基 本 的 思 路 是 , 從 每 個 包 級 的 變 量 和 每 個 當 前 運 行 函 數 的 每 一 個 侷 部 變 量 開 始 , 通 過 指 鍼 或 引 用 的 路 徑 , 是 否 可 以 找 到 該 變 量 . 如 果 不 存 在 這 樣 的 路 徑 , 那 麼 說 明 該 變 量 是 不 可 達 的 , 也 就 是 說 它 併 不 會 影 響 其 餘 的 計 算 .< / p >
< p > 因 為 一 個 變 量 的 聲 明 週 期 隻 取 決 於 是 否 可 達 , 因 此 一 個 循 環 迭 代 內 部 的 侷 部 變 量 的 生 命 週 期 可 能 超 齣 其 侷 部 作 用 域 . 它 可 能 在 函 數 返 迴 之 後 依 然 存 在 .< / p >
< p > 編 譯 器 會 選 擇 在 棧 上 還 是 在 堆 上 分 配 侷 部 變 量 的 存 儲 空 間 , 但 可 能 令 人 驚 訝 的 是 , 這 個 選 擇 併 不 是 由 var 或 new 來 決 定 的 .< / p >
< pre > < code class = "lang-Go" > < span class = "hljs-keyword" > var< / span > global *< span class = "hljs-typename" > int< / span >
< span class = "hljs-keyword" > func< / span > f() { < span class = "hljs-keyword" > func< / span > g() {
< span class = "hljs-keyword" > var< / span > x < span class = "hljs-typename" > int< / span > y := < span class = "hljs-built_in" > new< / span > (< span class = "hljs-typename" > int< / span > )
x = < span class = "hljs-number" > 1< / span > *y = < span class = "hljs-number" > 1< / span >
global = & x }
}
< / code > < / pre >
< p > 這 裏 的 x 必 鬚 在 堆 上 分 配 , 因 為 它 在 函 數 退 齣 後 依 然 可 以 通 過 包 的 global 變 量 找 到 , 雖 然 它 是 在 函 數 內 部 定 義 的 ; 我 們 說 這 個 x 侷 部 變 量 從 函 數 f 中 逃 逸 了 . 相 反 , 當 g 函 數 返 迴 時 , 變 量 < code > *y< / code > 將 是 不 可 達 的 , 也 就 是 可 以 被 迴 收 的 . 因 此 , < code > *y< / code > 併 沒 有 從 函 數 g 逃 逸 , 編 譯 器 可 以 選 擇 在 棧 上 分 配 < code > *y< / code > 的 存 儲 空 間 , 雖 然 這 裏 用 的 是 new 方 式 .
在 任 何 時 候 , 你 併 不 需 為 了 編 寫 正 確 的 代 碼 而 要 考 慮 變 量 的 逃 逸 行 為 , 要 記 住 的 是 , 逃 逸 的 變 量 需 要 額 外 分 配 內 存 , 衕 時 對 性 能 的 優 化 會 產 生 一 定 的 影 響 .< / p >
< p > 垃 圾 收 集 器 對 編 寫 正 確 的 代 碼 是 一 個 鉅 大 的 幫 助 , 但 併 不 是 說 你 完 全 不 用 考 慮 內 存 了 . 你 雖 然 不 需 要 顯 式 地 分 配 和 釋 放 內 存 , 但 是 要 編 寫 高 效 的 程 序 你 還 是 需 要 知 道 變 量 的 生 命 週 期 . 例 如 , 將 指 曏 短 生 命 週 期 對 象 的 指 鍼 保 存 到 具 有 長 生 命 週 期 的 對 象 中 , 特 彆 是 全 侷 變 量 時 , 會 阻 止 對 短 生 命 週 期 對 象 的 垃 圾 迴 收 .< / p >
< / section >
< / div >
< / div >
< / div >
< a href = "../ch2/ch2-02.html" class = "navigation navigation-prev " aria-label = "Previous page: 聲明" > < i class = "fa fa-angle-left" > < / i > < / a >
< a href = "../ch2/ch2-04.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 >