MST
星途 面试题库

面试题:Go语言中方法值在性能表现上与方法表达式有何不同

在Go语言里,方法值是通过对象调用方法后得到的可直接调用的函数值。请解释方法值在性能表现上与方法表达式的差异,并举出一个简单示例说明它们在实际使用场景中因性能不同可能导致选择不同的情况。
37.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

性能差异

  1. 方法值:通过对象调用方法后得到的可直接调用的函数值。在创建方法值时,会将接收者对象绑定到方法上,后续调用该方法值时,无需再指定接收者,直接调用效率较高,因为减少了接收者参数传递的开销。例如 obj := &SomeType{}; f := obj.Method; f(),这里 f 是方法值,调用 f 时不需要再指定 obj
  2. 方法表达式:它将方法当作普通函数,需要显式传递接收者参数。每次调用方法表达式时,都要传递接收者对象,相比方法值,多了参数传递的开销,在频繁调用场景下性能略低。例如 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 略好。如果在性能敏感且频繁调用的场景下,应该优先选择方法值;而在需要将方法当作普通函数传递等灵活性要求高的场景下,方法表达式更合适。