面试题答案
一键面试性能差异
- 方法值:通过对象调用方法后得到的可直接调用的函数值。在创建方法值时,会将接收者对象绑定到方法上,后续调用该方法值时,无需再指定接收者,直接调用效率较高,因为减少了接收者参数传递的开销。例如
obj := &SomeType{}; f := obj.Method; f()
,这里f
是方法值,调用f
时不需要再指定obj
。 - 方法表达式:它将方法当作普通函数,需要显式传递接收者参数。每次调用方法表达式时,都要传递接收者对象,相比方法值,多了参数传递的开销,在频繁调用场景下性能略低。例如
obj := &SomeType{}; f := (*SomeType).Method; f(obj)
,这里f
是方法表达式,调用f
时要传递obj
。
示例
package main
import (
"fmt"
"time"
)
type SomeType struct {
value int
}
func (s *SomeType) Method() {
// 模拟一些工作
time.Sleep(10 * time.Millisecond)
fmt.Println("Method called with value:", s.value)
}
func main() {
obj := &SomeType{value: 42}
// 方法值
start := time.Now()
methodValue := obj.Method
for i := 0; i < 10000; i++ {
methodValue()
}
elapsedValue := time.Since(start)
// 方法表达式
start = time.Now()
methodExpr := (*SomeType).Method
for i := 0; i < 10000; i++ {
methodExpr(obj)
}
elapsedExpr := time.Since(start)
fmt.Printf("Method value elapsed: %v\n", elapsedValue)
fmt.Printf("Method expression elapsed: %v\n", elapsedExpr)
}
在上述示例中,methodValue
是方法值,methodExpr
是方法表达式。通过循环多次调用,在这个简单的性能测试场景下,methodValue
由于不需要每次传递接收者对象,性能会比 methodExpr
略好。如果在性能敏感且频繁调用的场景下,应该优先选择方法值;而在需要将方法当作普通函数传递等灵活性要求高的场景下,方法表达式更合适。