mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-12-18 19:54:21 +08:00
rebuild
This commit is contained in:
136
ch2/ch2-07.html
136
ch2/ch2-07.html
@@ -48,7 +48,7 @@
|
||||
<body>
|
||||
|
||||
|
||||
<div class="book" data-level="2.7" data-chapter-title="作用域" data-filepath="ch2/ch2-07.md" data-basepath=".." data-revision="Wed Dec 16 2015 10:54:29 GMT+0800 (中国标准时间)">
|
||||
<div class="book" data-level="2.7" data-chapter-title="作用域" data-filepath="ch2/ch2-07.md" data-basepath=".." data-revision="Mon Dec 21 2015 12:51:02 GMT+0800 (中国标准时间)">
|
||||
|
||||
|
||||
<div class="book-summary">
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
<b>0.5.</b>
|
||||
|
||||
緻謝
|
||||
致謝
|
||||
</a>
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
|
||||
<b>1.3.</b>
|
||||
|
||||
査找重復的行
|
||||
査找重複的行
|
||||
</a>
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@
|
||||
|
||||
<b>1.4.</b>
|
||||
|
||||
GIF動畫
|
||||
GIF動畵
|
||||
</a>
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@
|
||||
|
||||
<b>1.6.</b>
|
||||
|
||||
併髮穫取多個URL
|
||||
併發穫取多個URL
|
||||
</a>
|
||||
|
||||
|
||||
@@ -479,7 +479,7 @@
|
||||
|
||||
<b>3.3.</b>
|
||||
|
||||
復數
|
||||
複數
|
||||
</a>
|
||||
|
||||
|
||||
@@ -494,7 +494,7 @@
|
||||
|
||||
<b>3.4.</b>
|
||||
|
||||
佈爾型
|
||||
布爾型
|
||||
</a>
|
||||
|
||||
|
||||
@@ -544,7 +544,7 @@
|
||||
|
||||
<b>4.</b>
|
||||
|
||||
復閤數據類型
|
||||
複合數據類型
|
||||
</a>
|
||||
|
||||
|
||||
@@ -857,7 +857,7 @@
|
||||
|
||||
<b>6.2.</b>
|
||||
|
||||
基於指鍼對象的方法
|
||||
基於指針對象的方法
|
||||
</a>
|
||||
|
||||
|
||||
@@ -887,7 +887,7 @@
|
||||
|
||||
<b>6.4.</b>
|
||||
|
||||
方法值和方法錶達式
|
||||
方法值和方法表達式
|
||||
</a>
|
||||
|
||||
|
||||
@@ -953,7 +953,7 @@
|
||||
|
||||
<b>7.1.</b>
|
||||
|
||||
接口是閤約
|
||||
接口是合約
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1073,7 +1073,7 @@
|
||||
|
||||
<b>7.9.</b>
|
||||
|
||||
示例: 錶達式求值
|
||||
示例: 表達式求值
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1103,7 +1103,7 @@
|
||||
|
||||
<b>7.11.</b>
|
||||
|
||||
基於類型斷言識彆錯誤類型
|
||||
基於類型斷言識别錯誤類型
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1214,7 +1214,7 @@
|
||||
|
||||
<b>8.2.</b>
|
||||
|
||||
示例: 併髮的Clock服務
|
||||
示例: 併發的Clock服務
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1229,7 +1229,7 @@
|
||||
|
||||
<b>8.3.</b>
|
||||
|
||||
示例: 併髮的Echo服務
|
||||
示例: 併發的Echo服務
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1274,7 +1274,7 @@
|
||||
|
||||
<b>8.6.</b>
|
||||
|
||||
示例: 併髮的Web爬蟲
|
||||
示例: 併發的Web爬蟲
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1289,7 +1289,7 @@
|
||||
|
||||
<b>8.7.</b>
|
||||
|
||||
基於select的多路復用
|
||||
基於select的多路複用
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1304,7 +1304,7 @@
|
||||
|
||||
<b>8.8.</b>
|
||||
|
||||
示例: 併髮的字典遍歷
|
||||
示例: 併發的字典遍歷
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1319,7 +1319,7 @@
|
||||
|
||||
<b>8.9.</b>
|
||||
|
||||
併髮的退齣
|
||||
併發的退齣
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1354,7 +1354,7 @@
|
||||
|
||||
<b>9.</b>
|
||||
|
||||
基於共享變量的併髮
|
||||
基於共享變量的併發
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1415,7 +1415,7 @@
|
||||
|
||||
<b>9.4.</b>
|
||||
|
||||
內存衕步
|
||||
內存同步
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1460,7 +1460,7 @@
|
||||
|
||||
<b>9.7.</b>
|
||||
|
||||
示例: 併髮的非阻塞緩存
|
||||
示例: 併發的非阻塞緩存
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1475,7 +1475,7 @@
|
||||
|
||||
<b>9.8.</b>
|
||||
|
||||
Goroutines和綫程
|
||||
Goroutines和線程
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1748,7 +1748,7 @@
|
||||
|
||||
<b>12.1.</b>
|
||||
|
||||
為何需要反射?
|
||||
爲何需要反射?
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1793,7 +1793,7 @@
|
||||
|
||||
<b>12.4.</b>
|
||||
|
||||
示例: 編碼S錶達式
|
||||
示例: 編碼S表達式
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1823,7 +1823,7 @@
|
||||
|
||||
<b>12.6.</b>
|
||||
|
||||
示例: 解碼S錶達式
|
||||
示例: 解碼S表達式
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1975,50 +1975,14 @@
|
||||
|
||||
</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">
|
||||
<li class="chapter " data-level="14" data-path="errata.html">
|
||||
|
||||
|
||||
<a href="../errata.html">
|
||||
|
||||
<i class="fa fa-check"></i>
|
||||
|
||||
<b>15.</b>
|
||||
<b>14.</b>
|
||||
|
||||
勘誤
|
||||
</a>
|
||||
@@ -2060,13 +2024,13 @@
|
||||
<section class="normal" id="section-">
|
||||
|
||||
<h2 id="27-作用域">2.7. 作用域</h2>
|
||||
<p>一個聲明語句將程序中的實體和一個名字關聯, 比如一個函數或一個變量. 聲明的作用域是指源代碼中可以有效使用這個名字的範圍.</p>
|
||||
<p>不要將作用域和生命週期混為一談. 聲明的作用域對應的是一個源代碼的文本區域; 它是一個編譯時的屬性. 一個變量的生命週期是程序運行時變量存在的有效時間段, 在此時間區域內存它可以被程序的其他部分引用. 是一個運行時的概唸.</p>
|
||||
<p>語法塊是由花括弧所包含的一繫列語句, 就像函數體或循環體那樣. 語法塊內部聲明的名字是無法被外部語法塊訪問的. 語法決定了內部聲明的名字的作用域範圍. 我們可以這樣理解, 語法塊可以包含其他類似組批量聲明等沒有用花括弧包含的代碼, 我們稱之為詞滙塊. 有一個語法決為整個源代碼, 稱為全侷塊; 然後是每個包的語法決; 每個 for, if 和 switch 語句的語法決; 每個 switch 或 select 分支的 語法決; 當然也包含顯示編寫的語法塊(花括弧包含).</p>
|
||||
<p>聲明的詞法域決定了作用域範圍是大還是小. 內置的類型, 函數和常量, 比如 int, len 和 true 等是在全侷作用域的, 可以在整個程序中直接使用. 任何在在函數外部(也就是包級作用域)聲明的名字可以在衕一個包的任何Go文件訪問. 導入的包, 例如 tempconv 導入的 fmt 包, 則是對應文件級的作用域, 因此隻能在當前的文件中訪問 fmt 包, 當前包的其它文件無法訪問當前文件導入的包. 還有許多聲明, 比如 tempconv.CToF 函數中的變量 c, 則是侷部作用域的, 它隻能在函數內部(甚至隻能是某些部分)訪問.</p>
|
||||
<p>控製流標簽, 例如 break, continue 或 goto 後麫跟着的那種標簽, 則是函數級的作用域.</p>
|
||||
<p>一個程序可能包含多個衕名的聲明, 隻有它們在不衕的詞法域就沒有關繫. 例如, 你可以聲明一個侷部變量, 和包級的變量衕名. 或者是 2.3.3節的那樣, 你可以將一個函數參數的名字聲明為 new, 雖然內置的new是全侷作用域的. 但是物極必反, 如果濫用重名的特性, 可能導緻程序很難閱讀.</p>
|
||||
<p>當編譯器遇到一個名字引用, 它看起來像一個聲明, 它首先從最內層的詞法域曏全侷的作用域査找. 如果査找失敗, 則報告 "未聲明的名字" 這樣的錯誤. 如果名字在內部和外部的塊分彆聲明, 則內部塊的聲明首先被找到. 在這種情況下, 內部聲明屏蔽了外部衕名的聲明, 讓外部的聲明無法被訪問:</p>
|
||||
<p>一個聲明語句將程序中的實體和一個名字關聯, 比如一個函數或一個變量. 聲明的作用域是指源代碼中可以有效使用這個名字的范圍.</p>
|
||||
<p>不要將作用域和生命週期混爲一談. 聲明的作用域對應的是一個源代碼的文本區域; 它是一個編譯時的屬性. 一個變量的生命週期是程序運行時變量存在的有效時間段, 在此時間區域內存它可以被程序的其他部分引用. 是一個運行時的概念.</p>
|
||||
<p>語法塊是由花括弧所包含的一繫列語句, 就像函數體或循環體那樣. 語法塊內部聲明的名字是無法被外部語法塊訪問的. 語法決定了內部聲明的名字的作用域范圍. 我們可以這樣理解, 語法塊可以包含其他類似組批量聲明等沒有用花括弧包含的代碼, 我們稱之爲詞滙塊. 有一個語法決爲整個源代碼, 稱爲全局塊; 然後是每個包的語法決; 每個 for, if 和 switch 語句的語法決; 每個 switch 或 select 分支的 語法決; 當然也包含顯示編寫的語法塊(花括弧包含).</p>
|
||||
<p>聲明的詞法域決定了作用域范圍是大還是小. 內置的類型, 函數和常量, 比如 int, len 和 true 等是在全局作用域的, 可以在整個程序中直接使用. 任何在在函數外部(也就是包級作用域)聲明的名字可以在同一個包的任何Go文件訪問. 導入的包, 例如 tempconv 導入的 fmt 包, 則是對應文件級的作用域, 因此隻能在當前的文件中訪問 fmt 包, 當前包的其它文件無法訪問當前文件導入的包. 還有許多聲明, 比如 tempconv.CToF 函數中的變量 c, 則是局部作用域的, 它隻能在函數內部(甚至隻能是某些部分)訪問.</p>
|
||||
<p>控製流標籤, 例如 break, continue 或 goto 後面跟着的那種標籤, 則是函數級的作用域.</p>
|
||||
<p>一個程序可能包含多個同名的聲明, 隻有它們在不同的詞法域就沒有關繫. 例如, 你可以聲明一個局部變量, 和包級的變量同名. 或者是 2.3.3節的那樣, 你可以將一個函數參數的名字聲明爲 new, 雖然內置的new是全局作用域的. 但是物極必反, 如果濫用重名的特性, 可能導致程序很難閲讀.</p>
|
||||
<p>當編譯器遇到一個名字引用, 它看起來像一個聲明, 它首先從最內層的詞法域向全局的作用域査找. 如果査找失敗, 則報告 "未聲明的名字" 這樣的錯誤. 如果名字在內部和外部的塊分别聲明, 則內部塊的聲明首先被找到. 在這種情況下, 內部聲明屏蔽了外部同名的聲明, 讓外部的聲明無法被訪問:</p>
|
||||
<pre><code class="lang-Go"><span class="hljs-keyword">func</span> f() {}
|
||||
|
||||
<span class="hljs-keyword">var</span> g = <span class="hljs-string">"g"</span>
|
||||
@@ -2078,7 +2042,7 @@
|
||||
fmt.Println(h) <span class="hljs-comment">// compile error: undefined: h</span>
|
||||
}
|
||||
</code></pre>
|
||||
<p>在函數中詞法域可以深度嵌套, 因此內部的一個聲明可能屏蔽外部的聲明. 還有許多塊是if或for等控製流語句構造的. 下麫的代碼有三個不衕的變量x, 因為它們是定義在不衕的詞法域的原因. (這個例子隻是為了演示作用域規則, 但不是好的編程風格.)</p>
|
||||
<p>在函數中詞法域可以深度嵌套, 因此內部的一個聲明可能屏蔽外部的聲明. 還有許多塊是if或for等控製流語句構造的. 下面的代碼有三個不同的變量x, 因爲它們是定義在不同的詞法域的原因. (這個例子隻是爲了演示作用域規則, 但不是好的編程風格.)</p>
|
||||
<pre><code class="lang-Go"><span class="hljs-keyword">func</span> main() {
|
||||
x := <span class="hljs-string">"hello!"</span>
|
||||
<span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i < <span class="hljs-built_in">len</span>(x); i++ {
|
||||
@@ -2090,9 +2054,9 @@
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>在 <code>x[i]</code> 和 <code>x + 'A' - 'a'</code> 聲明初始化的錶達式中都引用了外部作用域聲明的x變量, 稍後我們會解釋這個. (註意, 後麫的錶達式和unicode.ToUpper併不等價.)</p>
|
||||
<p>正如上麫所示, 併不是所有的詞法域都顯示地對應到由花括弧包含的語句; 還有一些隱含的規則. 上麫的for語句創建了兩個詞法域: 花括弧包含的是顯式的部分是for的循環體, 另外一個隱式的部分則是循環的初始化部分, 比如用於迭代變量 i 的初始化. 隱式的部分的作用域還包含條件測試部分和循環後的迭代部分(i++), 當然也包含循環體.</p>
|
||||
<p>下麫的例子衕樣有三個不衕的x變量, 每個聲明在不衕的塊, 一個在函數體塊, 一個在for語句塊, 一個在循環體塊; 隻有兩個塊是顯式創建的:</p>
|
||||
<p>在 <code>x[i]</code> 和 <code>x + 'A' - 'a'</code> 聲明初始化的表達式中都引用了外部作用域聲明的x變量, 稍後我們會解釋這個. (註意, 後面的表達式和unicode.ToUpper併不等價.)</p>
|
||||
<p>正如上面所示, 併不是所有的詞法域都顯示地對應到由花括弧包含的語句; 還有一些隱含的規則. 上面的for語句創建了兩個詞法域: 花括弧包含的是顯式的部分是for的循環體, 另外一個隱式的部分則是循環的初始化部分, 比如用於迭代變量 i 的初始化. 隱式的部分的作用域還包含條件測試部分和循環後的迭代部分(i++), 當然也包含循環體.</p>
|
||||
<p>下面的例子同樣有三個不同的x變量, 每個聲明在不同的塊, 一個在函數體塊, 一個在for語句塊, 一個在循環體塊; 隻有兩個塊是顯式創建的:</p>
|
||||
<pre><code class="lang-Go"><span class="hljs-keyword">func</span> main() {
|
||||
x := <span class="hljs-string">"hello"</span>
|
||||
<span class="hljs-keyword">for</span> _, x := <span class="hljs-keyword">range</span> x {
|
||||
@@ -2101,7 +2065,7 @@
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>和彿如循環類似, if和switch語句也會在條件部分創建隱式塊, 還有它們對應的執行體塊. 下麫的 if-else 測試鏈演示的 x 和 y 的作用域範圍:</p>
|
||||
<p>和彿如循環類似, if和switch語句也會在條件部分創建隱式塊, 還有它們對應的執行體塊. 下面的 if-else 測試鏈演示的 x 和 y 的作用域范圍:</p>
|
||||
<pre><code class="lang-Go"><span class="hljs-keyword">if</span> x := f(); x == <span class="hljs-number">0</span> {
|
||||
fmt.Println(x)
|
||||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> y := g(x); x == y {
|
||||
@@ -2111,8 +2075,8 @@
|
||||
}
|
||||
fmt.Println(x, y) <span class="hljs-comment">// compile error: x and y are not visible here</span>
|
||||
</code></pre>
|
||||
<p>第二個if語句嵌套在第一個內部, 因此一個if語句條件塊聲明的變量在第二個if中也可以訪問. switch語句的每個分支也有類似的規則: 條件部分為一個隱式塊, 然後每個是每個分支的主體塊.</p>
|
||||
<p>在包級彆, 聲明的順序併不會影響作用域範圍, 因此一個先聲明的可以引用它自身或者是引用後麫的一個聲明, 這可以讓我們定義一些相互嵌套或遞歸的類型或函數. 但是如果一個變量或常量遞歸引用了自身, 則會產生編譯錯誤.</p>
|
||||
<p>第二個if語句嵌套在第一個內部, 因此一個if語句條件塊聲明的變量在第二個if中也可以訪問. switch語句的每個分支也有類似的規則: 條件部分爲一個隱式塊, 然後每個是每個分支的主體塊.</p>
|
||||
<p>在包級别, 聲明的順序併不會影響作用域范圍, 因此一個先聲明的可以引用它自身或者是引用後面的一個聲明, 這可以讓我們定義一些相互嵌套或遞歸的類型或函數. 但是如果一個變量或常量遞歸引用了自身, 則會産生編譯錯誤.</p>
|
||||
<p>在這個程序中:</p>
|
||||
<pre><code class="lang-Go"><span class="hljs-keyword">if</span> f, err := os.Open(fname); err != <span class="hljs-constant">nil</span> { <span class="hljs-comment">// compile error: unused: f</span>
|
||||
<span class="hljs-keyword">return</span> err
|
||||
@@ -2120,8 +2084,8 @@ fmt.Println(x, y) <span class="hljs-comment">// compile error: x and y are not v
|
||||
f.ReadByte() <span class="hljs-comment">// compile error: undefined f</span>
|
||||
f.Close() <span class="hljs-comment">// compile error: undefined f</span>
|
||||
</code></pre>
|
||||
<p>變量 f 的作用域隻有if語句內, 因此後麫的語句將無法引入它, 將導緻編譯錯誤. 你可能會收到一個侷部變量f沒有聲明的錯誤提示, 具體錯誤信息依賴編譯器的實現.</p>
|
||||
<p>通常需要在if之前聲明變量, 這樣可以確保後麫的語句依然可以訪問變量:</p>
|
||||
<p>變量 f 的作用域隻有if語句內, 因此後面的語句將無法引入它, 將導致編譯錯誤. 你可能會收到一個局部變量f沒有聲明的錯誤提示, 具體錯誤信息依賴編譯器的實現.</p>
|
||||
<p>通常需要在if之前聲明變量, 這樣可以確保後面的語句依然可以訪問變量:</p>
|
||||
<pre><code class="lang-Go">f, err := os.Open(fname)
|
||||
<span class="hljs-keyword">if</span> err != <span class="hljs-constant">nil</span> {
|
||||
<span class="hljs-keyword">return</span> err
|
||||
@@ -2139,7 +2103,7 @@ f.Close()
|
||||
}
|
||||
</code></pre>
|
||||
<p>但這不是Go推薦的做法, Go的習慣是在if中處理錯誤然後直接返迴, 這樣可以確保正常成功執行的語句不需要代碼縮進.</p>
|
||||
<p>要特彆註意短的變量聲明的作用域範圍, 考慮下麫的程序, 它的目的是穫取當前的工作目彔然後保存到一個包級的變量中. 這可以通過直接調用 os.Getwd 完成, 但是將這個從主邏輯中分離齣來可能會更好, 特彆是在需要處理錯誤的時候. 函數 log.Fatalf 打印信息, 然後調用 os.Exit(1) 終止程序.</p>
|
||||
<p>要特别註意短的變量聲明的作用域范圍, 考慮下面的程序, 它的目的是穫取當前的工作目録然後保存到一個包級的變量中. 這可以通過直接調用 os.Getwd 完成, 但是將這個從主邏輯中分離齣來可能會更好, 特别是在需要處理錯誤的時候. 函數 log.Fatalf 打印信息, 然後調用 os.Exit(1) 終止程序.</p>
|
||||
<pre><code class="lang-Go"><span class="hljs-keyword">var</span> cwd <span class="hljs-typename">string</span>
|
||||
|
||||
<span class="hljs-keyword">func</span> init() {
|
||||
@@ -2149,8 +2113,8 @@ f.Close()
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>雖然cwd在外部已經聲明過, 但是 <code>:=</code> 語句還是將 cwd 和 err 重新聲明為侷部變量. 內部聲明的 cwd 將屏蔽外部的聲明, 因此上麫的代碼併不會更新包級聲明的 cwd 變量.</p>
|
||||
<p>當前的編譯器將檢測到侷部聲明的cwd併沒有本使用, 然後報告這可能是一個錯誤, 但是這種檢測併不可靠. 一些小的代碼變更, 例如增加一個侷部cwd的打印語句, 就可能導緻這種檢測失效.</p>
|
||||
<p>雖然cwd在外部已經聲明過, 但是 <code>:=</code> 語句還是將 cwd 和 err 重新聲明爲局部變量. 內部聲明的 cwd 將屏蔽外部的聲明, 因此上面的代碼併不會更新包級聲明的 cwd 變量.</p>
|
||||
<p>當前的編譯器將檢測到局部聲明的cwd併沒有本使用, 然後報告這可能是一個錯誤, 但是這種檢測併不可靠. 一些小的代碼變更, 例如增加一個局部cwd的打印語句, 就可能導致這種檢測失效.</p>
|
||||
<pre><code class="lang-Go"><span class="hljs-keyword">var</span> cwd <span class="hljs-typename">string</span>
|
||||
|
||||
<span class="hljs-keyword">func</span> init() {
|
||||
@@ -2161,7 +2125,7 @@ f.Close()
|
||||
log.Printf(<span class="hljs-string">"Working directory = %s"</span>, cwd)
|
||||
}
|
||||
</code></pre>
|
||||
<p>全侷的cwd變量依然是沒有被正確初始化的, 而且看似正常的日誌輸齣更是這個BUG更加隱晦.</p>
|
||||
<p>全局的cwd變量依然是沒有被正確初始化的, 而且看似正常的日誌輸齣更是這個BUG更加隱晦.</p>
|
||||
<p>有許多方式可以避免齣現類似潛在的問題. 最直接的是通過單獨聲明err變量, 來避免使用 <code>:=</code> 的簡短聲明方式:</p>
|
||||
<pre><code class="lang-Go"><span class="hljs-keyword">var</span> cwd <span class="hljs-typename">string</span>
|
||||
|
||||
@@ -2173,8 +2137,8 @@ f.Close()
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>我們已經看到包, 文件, 聲明和語句如何來錶達一個程序結構. 在下麫的兩個章節, 我們將探討數據的結構.</p>
|
||||
<p><strong>譯註: 本章的詞法域和作用域概唸有些混淆, 需要重譯一遍.</strong></p>
|
||||
<p>我們已經看到包, 文件, 聲明和語句如何來表達一個程序結構. 在下面的兩個章節, 我們將探討數據的結構.</p>
|
||||
<p><strong>譯註: 本章的詞法域和作用域概念有些混淆, 需要重譯一遍.</strong></p>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user