接口的golang地址和接口区别
golang address of interface and interface difference
我发现了很多类似的问题,但不是我想要的
请看下面的代码。
(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
To make it easier to remember these rules, it may be helpful to simply consider the pointer- and value-receiver methods separately from the method set. It is legal to call a pointer-valued method on anything that is already a pointer or whose address can be taken (as is the case in the above example). It is legal to call a value method on anything which is a value or whose value can be dereferenced (as is the case with any pointer; this case is specified explicitly in the spec).
我一头雾水,自己也搞不懂。
希望您能帮帮我,谢谢!
也许我可以尝试更详细地解释所有非常好的评论已经在说什么:
go 中的接口(大部分)是指针
如果另一种类型实现了接口定义的所有方法,则 Go 中的接口被实现(满足)。通常这是通过在类型的指针上添加方法来完成的,不是直接在类型上添加方法。
type SomeInterface interface {
SomeMethod string
}
type SomeStruct struct {} // often is a struct but does not have to be
// a method on the structs pointer
func (s *SomeStruct) SomeMethod string {
return ""
}
这样的结果:
SomeStruct
没有实现 SomeInterface,*SomeStruct
实现了!
- 一个接口(通常)已经是一个指针。
你的例子
var b bytes.Buffer
fmt.Fprintf(&b, "some text")
var w http.ResponseWriter
http.Error(w, "some error", 1)
类型bytes.Buffer
的变量b
是一个struct
,从源代码可以看出:
type Buffer struct {
buf []byte // contents are the bytes buf[off : len(buf)]
off int // read at &buf[off], write at &buf[len(buf)]
bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.
lastRead readOp // last read operation, so that Unread* can work correctly.
// FIXME: it would be advisable to align Buffer to cachelines to avoid false
// sharing.
}
如果你想将它用作类型io.Writer(接口),你需要得到一个bytes.Buffer
的指针,因为(通常)在go中使用指针方法:fmt.Fprintf(&b, "some text")
http.ResponseWriter 类型的变量 w
是一个 interface
:
type ResponseWriter interface {
Header() Header
Write([]byte) (int, error)
WriteHeader(statusCode int)
}
由于接口(通常)已经指向一些底层实现,我们可以在不使用指针的情况下使用它:http.Error(w, "some error", 1)
.
接口初始化
接口本身不能初始化使用!你总是需要一个结构或其他类型来实现接口,然后你可以初始化它并将它用作类型 SomeInterface
。
例如 here is the implementation of gin 对应 http.ResponseWriter
。从代码中可以看出,它的方法使用指针接收器。所以 http.ResponseWriter 已经是一个指向结构的指针。
免责声明
这只是试图使这个复杂主题听起来简单(希望如此)的一种方法。这不是技术上完整或完全准确的解释。尽量保持简单但尽可能准确。
我发现了很多类似的问题,但不是我想要的 请看下面的代码。
(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
To make it easier to remember these rules, it may be helpful to simply consider the pointer- and value-receiver methods separately from the method set. It is legal to call a pointer-valued method on anything that is already a pointer or whose address can be taken (as is the case in the above example). It is legal to call a value method on anything which is a value or whose value can be dereferenced (as is the case with any pointer; this case is specified explicitly in the spec).
我一头雾水,自己也搞不懂。 希望您能帮帮我,谢谢!
也许我可以尝试更详细地解释所有非常好的评论已经在说什么:
go 中的接口(大部分)是指针
如果另一种类型实现了接口定义的所有方法,则 Go 中的接口被实现(满足)。通常这是通过在类型的指针上添加方法来完成的,不是直接在类型上添加方法。
type SomeInterface interface {
SomeMethod string
}
type SomeStruct struct {} // often is a struct but does not have to be
// a method on the structs pointer
func (s *SomeStruct) SomeMethod string {
return ""
}
这样的结果:
SomeStruct
没有实现 SomeInterface,*SomeStruct
实现了!- 一个接口(通常)已经是一个指针。
你的例子
var b bytes.Buffer
fmt.Fprintf(&b, "some text")
var w http.ResponseWriter
http.Error(w, "some error", 1)
类型bytes.Buffer
的变量b
是一个struct
,从源代码可以看出:
type Buffer struct {
buf []byte // contents are the bytes buf[off : len(buf)]
off int // read at &buf[off], write at &buf[len(buf)]
bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.
lastRead readOp // last read operation, so that Unread* can work correctly.
// FIXME: it would be advisable to align Buffer to cachelines to avoid false
// sharing.
}
如果你想将它用作类型io.Writer(接口),你需要得到一个bytes.Buffer
的指针,因为(通常)在go中使用指针方法:fmt.Fprintf(&b, "some text")
http.ResponseWriter 类型的变量 w
是一个 interface
:
type ResponseWriter interface {
Header() Header
Write([]byte) (int, error)
WriteHeader(statusCode int)
}
由于接口(通常)已经指向一些底层实现,我们可以在不使用指针的情况下使用它:http.Error(w, "some error", 1)
.
接口初始化
接口本身不能初始化使用!你总是需要一个结构或其他类型来实现接口,然后你可以初始化它并将它用作类型 SomeInterface
。
例如 here is the implementation of gin 对应 http.ResponseWriter
。从代码中可以看出,它的方法使用指针接收器。所以 http.ResponseWriter 已经是一个指向结构的指针。
免责声明
这只是试图使这个复杂主题听起来简单(希望如此)的一种方法。这不是技术上完整或完全准确的解释。尽量保持简单但尽可能准确。