接口和地址运算符
Interfaces and address operators
我无法理解为什么当 return 类型是接口时可以使用地址运算符
func NewReader() IReader {
return &Reader{}
}
但是(当然)当 return 类型是结构时就不会了
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
。
- 所以类型
IReader
隐藏了它是指针的事实?
- 函数签名
func MyFuncReader(r IReader)
没有告诉我,一个指针或一个值被传递给了函数?
示例
- 带接口的完整示例 https://play.golang.org/p/1Db1Jybp0rP
- 没有界面的完整示例https://play.golang.org/p/nPtu09yhe0C
如果函数的 return 类型是接口类型,您可以 return 实现该接口的任何值。 Spec: Return statements:
The return value or values may be explicitly listed in the "return" statement. Each expression must be single-valued and assignable to the corresponding element of the function's result type.
在您的第一个示例中,Reader
具有带有 指针接收器 的方法,因此只有指向 Reader
(即 *Reader
)的指针实现IReader
界面。所以你有到return&Reader{}
.
如果你的函数有一个 return 类型的具体类型,你必须 return 那个具体类型的值,你不能 return a 的值指向该类型的指针。
当 return 类型是 Reader
func NewReader() Reader {
return &Reader{} // cannot use &Reader literal (type *Reader) as type Reader in return argument
}
您不能使用指向 Reader
类型的指针来代替 Reader
类型。原因是它们不是同一类型。
当您使用像 IReader
这样的接口作为 return 类型时,如
func NewReader() IReader {
return &Reader{}
}
它基本上意味着实现 IReader
接口方法的 任何 类型将被归类为实现该接口的类型,因此是可以接受的。由于类型 *Reader
在您的示例中实现了 IReader
类型,因此它是此处 NewReader 函数可接受的 return 值。这意味着如果我引入一个实现此接口的新 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
包进行检查时,此 returned 值的基础类型将是 dummy
.
我无法理解为什么当 return 类型是接口时可以使用地址运算符
func NewReader() IReader {
return &Reader{}
}
但是(当然)当 return 类型是结构时就不会了
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
。
- 所以类型
IReader
隐藏了它是指针的事实? - 函数签名
func MyFuncReader(r IReader)
没有告诉我,一个指针或一个值被传递给了函数?
示例
- 带接口的完整示例 https://play.golang.org/p/1Db1Jybp0rP
- 没有界面的完整示例https://play.golang.org/p/nPtu09yhe0C
如果函数的 return 类型是接口类型,您可以 return 实现该接口的任何值。 Spec: Return statements:
The return value or values may be explicitly listed in the "return" statement. Each expression must be single-valued and assignable to the corresponding element of the function's result type.
在您的第一个示例中,Reader
具有带有 指针接收器 的方法,因此只有指向 Reader
(即 *Reader
)的指针实现IReader
界面。所以你有到return&Reader{}
.
如果你的函数有一个 return 类型的具体类型,你必须 return 那个具体类型的值,你不能 return a 的值指向该类型的指针。
当 return 类型是 Reader
func NewReader() Reader { return &Reader{} // cannot use &Reader literal (type *Reader) as type Reader in return argument }
您不能使用指向 Reader
类型的指针来代替 Reader
类型。原因是它们不是同一类型。
当您使用像 IReader
这样的接口作为 return 类型时,如
func NewReader() IReader { return &Reader{} }
它基本上意味着实现 IReader
接口方法的 任何 类型将被归类为实现该接口的类型,因此是可以接受的。由于类型 *Reader
在您的示例中实现了 IReader
类型,因此它是此处 NewReader 函数可接受的 return 值。这意味着如果我引入一个实现此接口的新 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
包进行检查时,此 returned 值的基础类型将是 dummy
.