提问人:nuclear 提问时间:8/28/2018 更新时间:8/29/2018 访问量:2242
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 和字节。缓冲区实现 io。编写器界面,所以我认为它们应该具有相同的行为。
当我更改为
http.Error(&w,http.StatusText(http.StatusBadRequest),http.StatusBadRequest)
Jetbrains Goland告诉我
Cannot use '&w' (type *http.ResponseWriter) as type ResponseWriter
我想知道为什么“&”可以工作,而另一个不起作用?buf
我用谷歌搜索了一下,有人说当将值传递给函数时,它可以引用&w
但另一种说法是,如果你传递一个指针,它可以尊重价值
与 https://github.com/golang/go/wiki/MethodSets#variables 相比
为了便于记住这些规则,简单地将指针和值接收器方法与方法集分开考虑可能会有所帮助。对已经是指针或可以获取其地址的任何内容调用指针值方法是合法的(如上面示例中的情况)。对任何值或其值可以取消引用的事物调用值方法是合法的(就像任何指针一样;这种情况在规范中明确指定)。
我完全糊涂了,我自己也听不懂。 我希望你能帮助我,谢谢!
答:
也许我可以尝试更详细地解释所有非常好的评论已经在说什么:
接口(大部分)是 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)
从源代码中可以看出,类型的变量是:b
bytes.Buffer
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 类型。编写器(接口)你需要得到一个指针,因为(通常)指针方法在go中使用:bytes.Buffer
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)
接口初始化
接口本身无法初始化和使用!你总是需要一个结构或其他类型来实现接口,然后你可以初始化它并将其用作类型。
例如,这里是 gin for a 的实现。从代码中可以看出,它使用指针接收器作为其方法。所以 http.ResponseWriter 已经是指向结构的指针。SomeInterface
http.ResponseWriter
免責聲明
这只是试图让这个复杂的话题听起来简单的一种方式(希望如此)。这在技术上不是一个完整或完全准确的解释。尽量保持简单,但尽可能准确。
评论
bytes.Buffer
是具体类型,是接口类型。关于方法的指针/值接收器的注释是无关的。http.ResponseWriter
http.Error
http.ResponseWriter
*http.ResponseWriter
func Error(w ResponseWriter, error string, code int)
ResponseWriter
io.Writer
http.ResponseWriter