求教:在程序中出现错误type *http.Request has no field or method Cancel

云幻无心sky · · 3294 次点击
* 之前正好看过[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
更多评论
polaris
社区,需要你我一同完善!
你代码中有 request.Cancel 这样的调用?
#1
有,http中没有定义cancel函数吗?
#2