2012-07-08 60 views
15

從我規範的閱讀:Go中短變量聲明和長變量聲明之間的關閉範圍區別是什麼?

短變量聲明...是一個常規變量 聲明與初始化表達式,但沒有一個類型速記......

http://golang.org/ref/spec

我原以爲兩者是相同的:

var f func() 
f = func() { 
    ... 
} 

f := func() { 
    ... 
} 

但似乎他們不是。我試圖總結外函數內自遞歸函數,但這個工程:

func myOuter() { 
    var f func() 

    f = func() { 
     f() 
    } 

    f() 
} 

但是這不,說在內部函數undefined: f

func myOuter() { 
    f := func() { 
     f() 
    } 

    f() 
} 

那麼有什麼區別? 有沒有什麼辦法可以用短格式聲明來寫這個或者我必須把它寫出來?

+0

謝謝Kissaki,我明顯粘貼了兩次錯誤的相同的東西。 – Joe 2012-07-08 13:25:17

回答

14

f := func() { /* ... */ }var f func() = func() { /* ... */ }完全相同(但只有後者才允許在包級別)。在您的具體情況下,兩種變體都不會起作用,因爲聲明將從右向左進行評估。解決辦法是 - 如您已經建議的 - 將聲明分成兩部分。一個用於聲明變量,另一個用於賦予遞歸函數。

+1

謝謝!我的訂單或聲明沒有發生。 – Joe 2012-07-08 12:42:04

+0

啊!現在我必須再次解除我的代碼,謝謝你的洞察! – 2014-02-24 21:02:02

0

在一個條件下,您的前兩個代碼示例在語義上是相同的:正在分配給您的變量的表達式需要在編譯時解析。

除了當您試圖分配引用您剛剛聲明的變量(或函數)的表達式時,這在每種情況下都是相同的。這裏的問題在於,因爲golang是以右關聯的方式解析的,所以它會嘗試在將它分配給左邊之前,在右邊鍵入解析表達式。如果引用declare-assign運算符左側的變量,則引用編譯器尚不知道的變量,因此undefined: f

,將產生類似的結果又如:

x := x + 1 

雖然這是很不常見的人嘗試,因爲它是更明顯的是,X尚未分配。