Go 中 interface{}(或 any)作为方法参数时,传值和传指针有什么区别?你写过这样的代码吗?

  func Foo(v interface{}) {
      // ...
  }

  func Bar(v *interface{}) {
      // ...
  }

  这两个签名有什么区别?应该怎么选?

func Foo(v interface{})     // 传值:接受任意类型的值
func Bar(v *interface{})    // 传指针:只接受 *interface{} 类型

补充——关于interface

interface{}(空接口)→ runtime.eface
// src/runtime/type.go
type eface struct {
    _type _type   // 指向具体类型的元信息
    data  unsafe.Pointer  // 指向实际值的指针
}

只有两个字段:
_type — 指针,指向一个描述类型元数据的结构(类型名、大小、哈希、对齐方式等)。所有类型在编译期都会生成对应的 _type 对象,存在静态数据段里。
data — 一个 unsafe.Pointer,指向被装箱的值的*副本。

非空接口(比如 io.Reader)→ runtime.iface
type iface struct {
    tab  *itab          // 接口表:关联具体类型和接口方法集
    data unsafe.Pointer // 指向实际值
}

多了个 itab,它额外缓存了方法跳转表