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(Method): 用于替自定义类型(包括 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 的思维下两者各夹杂一点,十分奇妙。
延伸阅读
- 组合优于继承? - iThome 林信良
- Go by Example: Methods
- Methods in Go - flaviocopes
- 学习 Go interface 实践多型 - WebDong