【发布时间】:2019-02-03 07:01:23
【问题描述】:
我发现了很多类似的问题,但不是我想要的 请看下面的代码。
(1)
var buf bytes.Buffer
fmt.Fprint(&buf,"test")
(2)
var w http.ResponseWriter
http.Error(w,http.StatusText(http.StatusBadRequest),http.StatusBadRequest)
http.ResponseWriter 和 bytes.Buffer 都实现了 io.Writer 接口,所以我认为它们应该具有相同的行为。
当我换成
http.Error(&w,http.StatusText(http.StatusBadRequest),http.StatusBadRequest)
jetbrains goland 告诉我
Cannot use '&w' (type *http.ResponseWriter) as type ResponseWriter
我想知道为什么 buf 有 '&' 可以工作,但另一个不工作?
我google了一下,有人说传值给函数的时候可以参考&w
但另一个说如果你传递一个指针,它可以尊重值
来自https://github.com/golang/go/wiki/MethodSets#variables
为了更容易记住这些规则,将指针和值接收器方法与方法集分开考虑可能会有所帮助。在任何已经是指针或可以获取其地址的东西上调用指针值方法是合法的(如上例中的情况)。对任何值或可以取消引用的值调用值方法是合法的(任何指针的情况都是如此;这种情况在规范中明确指定)。
我完全糊涂了,我自己无法理解。 希望您能帮帮我,谢谢!
【问题讨论】:
-
bytes.Buffer是具体类型,http.ResponseWriter是接口类型。关于方法的指针/值接收器的注释是无关的。 -
函数
http.Error需要一个http.ResponseWriter,但你传递的是一个*http.ResponseWriter(如错误所示)。这是函数参数(不是方法接收器)的错误类型。 -
如果您看到
func Error(w ResponseWriter, error string, code int)的定义,它需要ResponseWriter而不是指向它的指针。这是错误背后的原因,而不是您正在考虑的原因。 -
你真的应该深入研究 Go 的类型系统。这不是神奇地或随机地将 & 和 * 放在东西之前。您必须了解不同的类型,例如结构类型 (bytes.Buffer) 和接口类型 (http.ResponseWriter),并了解方法集。所以不是得到这个答案的正确地方。你可以试试 reddit 或 golang-nuts。
-
两者都是
io.Writers,是的,但两者都不是http.ResponseWriters。
标签: pointers go interface pass-by-reference pass-by-value