2016-12-03 60 views
6

我在Go for Go中編寫解析器,並測試它我從github項目下載了一堆文件。
https://github.com/andlabs/ui碰見含有這一段代碼文件:Go是一個未命名的參數嗎?

func moveLabel(*Button) { 
    from := movingCurrent 
    to := 0 
    if from == 0 { 
     to = 1 
    } 
    movingBoxes[from].Delete(0) 
    movingBoxes[to].Append(movingLabel, false) 
    movingCurrent = to 
} 

它混淆我一點看一個指向Button沒有名字作爲函數參數,這使得不可能參考從內側功能。
但是,考慮到編譯器沒有抱怨,它似乎在語法上是正確的。
Go中unamed函數參數的用途是什麼?

+0

增加了更多的細節,解釋(基於規格)和鏈接到答案。 – icza

回答

8

未命名的參數是完全有效的。該Parameter declaration從規格:

ParameterDecl = [ IdentifierList ] [ "..." ] Type . 

正如你所看到的,IdentifierList(標識符名稱或名稱)是在方括號,這意味着它的可選。只有Type是必需的。

原因是因爲名稱對於調用方法或函數的人來說並不重要。重要的是參數的類型和順序。這在這個答案中有詳細描述:Getting method parameter names in Golang

通常您可以命名變量和參數,以便您可以引用它們。

當你沒有命名的時候,這是因爲你不想引用它。

所以這個問題應該是:爲什麼我不想引用一個參數?

例如,因爲參數「存在」(已通過),但您不需要它,您不想使用它。如果我不需要它,爲什麼它會在那裏?

因爲某人或某事規定有特定的參數。例如,你想實現一個接口,或者你想傳遞一個函數值,其簽名由預期的函數類型定義。

我們來看一個例子。我們有以下MyWriter接口:

type MyWriter interface { 
    Write(p []byte) error 
} 

簡化io.Writer只返回一個錯誤,但不會報告寫入的字節數。如果你想提供剛剛丟棄(類似於ioutil.Discard)數據的實現,那麼不使用執行(不需要使用)它的參數:

type DiscardWriter struct{} 

func (DiscardWriter) Write([]byte) error { return nil } 

而這一切:我們不」不使用接收器,我們不使用參數。兩者都可以是未命名的。並且實現完全按照它應該做的。

這樣做(使用未命名的參數)文檔該值不被使用/引用。

另一個原因可以是提供轉發兼容性。如果你釋放一個庫,你不能改變或擴展參數列表而不破壞向後兼容性(並且在Go中沒有函數重載:如果你想要兩個具有不同參數的變體,它們的名稱也必須不同)。因此,您可以儘早使用其他參數聲明導出的函數或方法,但由於您尚未使用它們,因此可能會將其保留爲未命名。在這個答案中詳細說明了這樣一個例子:Why does Go allow compilation of unused function parameters?

這裏需要注意的一件事是,你不能混合命名參數和未命名參數。如果你命名一些,你必須命名所有。如果你並不需要所有的,你可以在這個例子中使用blank identifier,如:

它與"Hello"文本對所有請求響應一個簡單的Web服務器:

http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { 
    io.WriteString(w, "Hello") 
}) 
panic(http.ListenAndServe(":8080", nil)) 

處理函數發送回"Hello"文本僅使用響應寫入器w,但不使用請求結構,因此使用空白標識符作爲其名稱。

另一個相關的問題:

Why must we declare a variable name when adding a method to a struct in Golang?

也有點關係,但對於使用/命名返回值:

Return map like 'ok' in Golang on normal functions