不了解 Go 中的组合
Don't understand composition in Go
在下面的示例中,我将 http.ResponseWriter
嵌入到我自己的名为 Response
的结构中。我还添加了一个名为 Status
的额外字段。为什么我不能从我的 root
处理程序函数中访问该字段?
当我在我的根处理函数中打印出 w
的类型时,它说它是 main.Response
类型,这似乎是正确的,当我打印出结构的值时,我可以看到 Status
在那里。为什么我去w.Status
访问不了?
这是标准输出的内容:
main.Response
{ResponseWriter:0xc2080440a0 Status:0}
代码:
package main
import (
"fmt"
"reflect"
"net/http"
)
type Response struct {
http.ResponseWriter
Status int
}
func (r Response) WriteHeader(n int) {
r.Status = n
r.ResponseWriter.WriteHeader(n)
}
func middleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
resp := Response{ResponseWriter: w}
h.ServeHTTP(resp, r)
})
}
func root(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("root"))
fmt.Println(reflect.TypeOf(w))
fmt.Printf("%+v\n", w)
fmt.Println(w.Status) // <--- This causes an error.
}
func main() {
http.Handle("/", middleware(http.HandlerFunc(root)))
http.ListenAndServe(":8000", nil)
}
w
是 http.ResponseWriter
类型的变量。 ResponseWriter
没有字段或方法 Status
,只有您的 Response
类型。
http.ResponseWriter
是一种接口类型,并且由于您的 Response
类型实现了它(因为它嵌入了 ResponseWriter
),因此 w
变量可能包含动态值输入 Response
(在你的情况下它确实如此)。
但是要访问 Response.Status
字段,您必须将其转换为 Response
类型的值。为此使用 Type assertion:
if resp, ok := w.(Response); ok {
// resp is of type Response, you can access its Status field
fmt.Println(resp.Status) // <--- properly prints status
}
在下面的示例中,我将 http.ResponseWriter
嵌入到我自己的名为 Response
的结构中。我还添加了一个名为 Status
的额外字段。为什么我不能从我的 root
处理程序函数中访问该字段?
当我在我的根处理函数中打印出 w
的类型时,它说它是 main.Response
类型,这似乎是正确的,当我打印出结构的值时,我可以看到 Status
在那里。为什么我去w.Status
访问不了?
这是标准输出的内容:
main.Response
{ResponseWriter:0xc2080440a0 Status:0}
代码:
package main
import (
"fmt"
"reflect"
"net/http"
)
type Response struct {
http.ResponseWriter
Status int
}
func (r Response) WriteHeader(n int) {
r.Status = n
r.ResponseWriter.WriteHeader(n)
}
func middleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
resp := Response{ResponseWriter: w}
h.ServeHTTP(resp, r)
})
}
func root(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("root"))
fmt.Println(reflect.TypeOf(w))
fmt.Printf("%+v\n", w)
fmt.Println(w.Status) // <--- This causes an error.
}
func main() {
http.Handle("/", middleware(http.HandlerFunc(root)))
http.ListenAndServe(":8000", nil)
}
w
是 http.ResponseWriter
类型的变量。 ResponseWriter
没有字段或方法 Status
,只有您的 Response
类型。
http.ResponseWriter
是一种接口类型,并且由于您的 Response
类型实现了它(因为它嵌入了 ResponseWriter
),因此 w
变量可能包含动态值输入 Response
(在你的情况下它确实如此)。
但是要访问 Response.Status
字段,您必须将其转换为 Response
类型的值。为此使用 Type assertion:
if resp, ok := w.(Response); ok {
// resp is of type Response, you can access its Status field
fmt.Println(resp.Status) // <--- properly prints status
}