对于普通结构体作为接收者,值和指针并没有区别。
(以下代码摘抄自Go In Action 中文版)
type defaultMatcher struct{} // 方法声明为使用 defaultMatcher 类型的值作为接收者 func (m defaultMatcher) Search(feed *Feed, searchTerm string) // 声明一个指向 defaultMatcher 类型值的指针 dm := new(defaultMatch) // 编译器会解开 dm 指针的引用,使用对应的值调用方法 dm.Search(feed, "test") // 方法声明为使用指向 defaultMatcher 类型值的指针作为接收者 func (m *defaultMatcher) Search(feed *Feed, searchTerm string) // 声明一个 defaultMatcher 类型的值 var dm defaultMatch // 编译器会自动生成指针引用 dm 值,使用指针调用方法 dm.Search(feed, "test")使用一个空结构声明了一个名叫 defaultMatcher 的结构类型。空结构
在创建实例时,不会分配任何内存。这种结构很适合创建没有任何状态的类型。对于默认匹配器
来说,不需要维护任何状态,所以我们只要实现对应的接口就行。
因为大部分方法在被调用后都需要维护接收者的值的状态,所以,一个最佳实践是,将方法的接收者声明为指针。对于 defaultMatcher 类型来说,使用值作为接收者是因为创建一个defaultMatcher 类型的值不需要分配内存。由于 defaultMatcher 不需要维护状态,所以不需要指针形式的接收者。
与直接通过值或者指针调用方法不同,如果通过接口类型的值调用方法,规则有很大不同,使用指针作为接收者声明的方法,只能在接口类型的值是一个指针的时候被调用。使用值作为接收者声明的方法,在接口类型的值为值或者指针时,都可以被调用。
// 方法声明为使用指向 defaultMatcher 类型值的指针作为接收者 func (m *defaultMatcher) Search(feed *Feed, searchTerm string) // 通过 interface 类型的值来调用方法 var dm defaultMatcher var matcher Matcher = dm // 将值赋值给接口类型 matcher.Search(feed, "test") // 使用值来调用接口方法 > go build cannot use dm (type defaultMatcher) as type Matcher in assignment // 方法声明为使用 defaultMatcher 类型的值作为接收者 func (m defaultMatcher) Search(feed *Feed, searchTerm string) // 通过 interface 类型的值来调用方法 var dm defaultMatcher var matcher Matcher = &dm // 将指针赋值给接口类型 matcher.Search(feed, "test") // 使用指针来调用接口方法 > go build Build Successful