通过net/http
和相关库中的一些go资料,我发现something使我感到好奇。我正在这里查看版本1.12。
func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.Request, res *http.Response) {
...
hj, ok := rw.(http.Hijacker)
...
conn, brw, err := hj.Hijack()
...
}
我已经在更多地方以及标准库之外看到了类似的东西。这是怎么回事在实现特定断言之前,是否隐藏了接口实现的某些方法?为什么我不能只调用Hijack()
对象上的rw
?
答案 0 :(得分:0)
方法似乎是隐藏的,因为该函数采用接口类型。 http.ResponseWriter
的接口未定义Hijack()
方法。这是在http.Hijacker
界面中定义的。具体类型可以实现多个接口。但是,即使将这种具体类型传递到其类型定义为接口的范围中,也无法访问其他方法。因此,在有疑问的示例中,执行类型声明以使Hijack()
方法可用。
一些示例(playground):
package main
import (
"fmt"
)
type Ship interface {
Load(containers []string)
Condition() []string
}
type Sea interface {
Draft() int
}
// seaShip implements the Sea and Ship interfaces
type seaShip struct {
containers []string
}
// Load is only part of the Ship interface
func (ss *seaShip) Load(containers []string) {
ss.containers = append(ss.containers, containers...)
}
// Condition is only part of the Ship interface
func (ss *seaShip) Condition() []string {
return ss.containers
}
// Draft is only part of the Sea interface
func (ss *seaShip) Draft() int {
return len(ss.containers)
}
// Pirates is not defined in any interface and therefore can only be called on the concrete type
func (ss *seaShip) Pirates() string {
return "Help!"
}
// NewShip returns an implementation of the Ship interface
func NewShip() Ship {
return &seaShip{}
}
func main() {
ship := NewShip()
ship.Load([]string{"Beer", "Wine", "Peanuts"})
fmt.Println(ship.Condition())
// Won't compile, method is not part of interface!
// fmt.Println(ship.Draft())
// Assert to make Draft() available
sea := ship.(Sea)
fmt.Println(sea.Draft())
// Won't compile, methods are not part of interface!
// fmt.Println(sea.Condition())
// fmt.Println(sea.Pirates())
// Assert to the concrete type makes all methods available
ss := sea.(*seaShip)
fmt.Println(ss.Condition())
fmt.Println(ss.Pirates())
}