Go Receiver Function
第一次看到 Go 的 Receiver Function 會覺得這是啥怪語法,函式名前面還能接收參數?
type User struct { name string}
// receiver functionfunc (u User) Greet() { fmt.Println("Hello, my name is", u.name)}
func main() { u := User{name: "Riceball"} u.Greet()}
Go 語言提倡「Composition over inheritance」(組合優於繼承),並極力追求程式碼的簡潔性,以此迴避 class-based OOP 所帶來的複雜性。因此,Go 並不直接提供繼承機制,而是透過以下三個核心要素,來達到類似 OOP 的模式:
- Structs: 用於定義資料的結構。
- Receiver Functions: 用於為自定義類型(包括 struct、基於內建類型的自定義類型等)定義相關聯的方法和行為。
- Interfaces: 用於實現多型(polymorphism)。
其他語言相同範例
JavaScript
const user = { name: "Riceball", greet() { console.log("Hello, my name is", this.name) }}
user.greet()
Java
class User { private String name;
public User(String name) { this.name = name; }
public void greet() { System.out.println("Hello, my name is " + this.name); }}
public class Main { public static void main(String[] args) { User u = new User("Riceball"); u.greet(); // Hello, my name is Riceball }}
總結
Go 的 Receiver Function 本質上仍然是一個獨立的函式,它只是透過特殊的語法,將該函式「綁定」到一個特定的型別上,使其能夠以物件導向的風格被呼叫。這種設計巧妙地平衡了物件導向的封裝性與 Go 追求的簡潔性。
不過相較於 person.greet("Hi")
我還是更偏好單純函式 greet("Hi", person)
的思考方式。
- 一個是函式是資料的一部分。
- 一個是函式資料相互獨立的。
而在撰寫 Go 的思維下兩者各參雜一點,十分奇妙。