2016-08-22 164 views
2

我剛剛開始學習Go,並且有些事情引起了我的注意。通過變量訪問Go函數

功能,如:

delete(map, "Answer") // for maps 
append(slice, 0) // for slices 
len(slice), cap(slice) // again for slices 

等。作爲來自C語言的人,我想知道:

1)可以通過變量本身調用這些函數嗎(如map.delete("Answer"))?

2)這是一種常見的做法(定義一個泛型函數並讓它找出它的類型以及它應該做什麼),還是僅僅用於內置類型。例如,如果我想定義自己的類型,如MyCoolLinkedList,我應該定義len並追加型的內部功能,並讓它們稱爲像

list := new(MyCoolLinkedList) 
list.len() 

,或者我應該確定接收名單,像函數:

len(list) 

回答

2

1 - 不能將內置方法「附加」爲類型或值,例如

m := map[int]string{1: "one"} 
m.delete(1) 

是編譯時錯誤,您可以verify easily。但爲了緩解「痛苦」,它提供了幾個可以接受不同類型值的函數。它們是內置的,因爲 - 如前所述 - 由於缺乏泛型,它們需要編譯器的幫助才能接受不同類型的值。有些還接受類型而不是表達式作爲第一個參數(例如make([]int, 1)),這也是您無法創建的。內置函數沒有標準的Go類型,它們只能出現在call expressions中。

您不能創建接受不同類型值的函數。話雖如此,當您創建自己的類型併爲其創建一個「函數」時,建議將其聲明爲method而不是輔助函數;就好像「函數」在您的具體類型上運行一樣,您無法將其用於其他類型。

所以是有意義的聲明它作爲一種方法,然後你就可以把它更加「優雅」像

value.Method() 

作爲一個方法也是「罪狀」向類型的method set,如果您需要實現一個接口,例如在MyCoolLinkedList的情況下,實施sort.Interface以便能夠對列表進行排序是有意義的,例如需要Len() int方法。

通過輔助函數選擇方法還具有以下優點:您的方法可通過反射獲得。您可以使用reflect程序包列出並調用某種類型的方法,但不能對「正義」函數執行相同的操作。