程序导入包“net/http”
go版本:1.4.3
请问这个问题是什么原因,有大神知道吗?
* 之前正好看过[ctxhttp](https://github.com/golang/net/tree/master/context/ctxhttp),发现其中Go1.4和Go1.5对于request的Cancelation的处理是不一样的。
* 简单来说:
Cancel(channel)是Go1.5开始新增加在http.Request这个结构体中的。如果你看最新的文档,然后直接在老版本的Go(比如Go1.4.3)中使用request.Cancel,那么就可能遇到这个问题。
* 解决办法也很简单:
* 升级到Go1.6。
* 做的好点的话,可以使用Build Constraints来条件编译,分别支持Go1.4和Go1.5之后的版本。
* PS: 看到你这个问题,顺便回去学习了下ctxhttp中如何使用build constraints来条件编译的。然后整理了一篇文章 <https://github.com/northbright/Notes/blob/master/Golang/build/fix-the-http-request-has-no-field-or-method-cancel-issue.md>, 希望对你有用:
# Fix the `*http.Request has no field or method Cancel` Issue
#### Description
* We got the error: `type *http.Request has no field or method Cancel`
#### Root Cause
* `Cancel(channel)` is added in `http.Reqeust` since **Go1.5**
* Go1.5 -- the new `Cancel(channel)` is added in `http.Request`
<https://github.com/golang/go/blob/release-branch.go1.5/src/net/http/request.go>
type Request struct {
......
// Cancel is an optional channel whose closure indicates that the client
// request should be regarded as canceled. Not all implementations of
// RoundTripper may support Cancel.
//
// For server requests, this field is not applicable.
Cancel <-chan struct{}
}
* Go1.4.3 -- **NO** such `Cancel` field
<https://github.com/golang/go/blob/release-branch.go1.4/src/net/http/request.go>
* We used old version Go(less than Go1.5, Ex: Go1.4.3)
* Our code(or 3rd party library) accessed `request.Cancel`
#### Solutuion
* Upgrade to Go1.6 :-)
* Use [Build Constraints](https://godoc.org/go/build#hdr-Build_Constraints) for conditional build.
We can follow [ctxhttp](https://github.com/golang/net/tree/master/context/ctxhttp) to access `Request.Cancel` for Go1.5 and keep compatible with Go1.4:
* [cancelreq.go](https://github.com/golang/net/blob/master/context/ctxhttp/cancelreq.go)(>= Go1.5)
// +build go1.5
package ctxhttp
import "net/http"
func canceler(client *http.Client, req *http.Request) func() {
// TODO(djd): Respect any existing value of req.Cancel.
ch := make(chan struct{})
req.Cancel = ch
return func() {
close(ch)
}
}
* [cancelreq_go14.go](https://github.com/golang/net/blob/master/context/ctxhttp/cancelreq_go14.go)(< Go1.5)
// +build !go1.5
package ctxhttp
import "net/http"
type requestCanceler interface {
CancelRequest(*http.Request)
}
func canceler(client *http.Client, req *http.Request) func() {
rc, ok := client.Transport.(requestCanceler)
if !ok {
return func() {}
}
return func() {
rc.CancelRequest(req)
}
}
#### References
* [Build Constraints](https://godoc.org/go/build#hdr-Build_Constraints)
* [Use Build Constraints for Conditional Build](https://github.com/northbright/Notes/blob/master/Golang/build/use-build-constraints-for-conditional-build.md)
#4
更多评论