接口和地址运算符



我有一个问题,无法理解为什么当返回类型是接口时可以使用地址运算符

func NewReader() IReader {
return &Reader{}
}

但是(当然(当返回类型是结构时不是

func NewReader() Reader {
return &Reader{} // cannot use &Reader literal (type *Reader) as type Reader in return argument
}

稍后的函数签名是func MyFuncReader(r IReader),但是reflect.TypeOf(r)*main.Reader

  1. 所以类型IReader隐藏了它是指针的事实
  2. 函数签名func MyFuncReader(r IReader)没有告诉我,一个指针或一个值被传递给了函数

样品

  1. 带接口的完整样本https://play.golang.org/p/1Db1Jybp0rP
  2. 无接口的完整样本https://play.golang.org/p/nPtu09yhe0C

如果函数的返回类型是接口类型,则可以返回实现该接口的任何值。规格:退货声明:

返回值可以显式地列在";返回";陈述每个表达式都必须是单值的,并且可以赋值给函数结果类型的相应元素。

在您的第一个示例中,Reader具有带有指针接收器的方法,因此只有指向Reader的指针(即*Reader(实现IReader接口。因此您必须返回&Reader{}

如果函数的返回类型为具体类型,则必须返回该具体类型的值,而不能返回指向该类型的指针值。

当返回类型为Reader

func NewReader() Reader {
return &Reader{} // cannot use &Reader literal (type *Reader) as type Reader in return argument
}

您不能使用指向Reader类型的指针来代替Reader类型。原因是他们不属于同一类型。

当您使用像IReader这样的接口作为中的返回类型时

func NewReader() IReader {
return &Reader{}
}

这基本上意味着实现IReader接口方法的任何类型都将被归类为实现该接口的类型,因此是可以接受的。由于类型*Reader实现了示例中的IReader类型,因此它是NewReader函数的可接受返回值。这意味着如果我引入一个新的type来实现这个接口,比如

type dummy int
func (d dummy) GetCount() int {
return d
}
func (d dummy) IncreaseCount() {
fmt.Println("Increased count: %d", d)
}

然后我可以做一些类似的事情

func NewReader() IReader {
var d dummy
d = 5
return d
}

而且它仍然有效。在使用reflect包进行检查时,此返回值的基本类型将是dummy

最新更新