Golang 方法接收者是值还是指针问题

对于普通结构体作为接收者,值和指针并没有区别。

(以下代码摘抄自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
原文地址:https://www.cnblogs.com/gardenofhu/p/9115284.html