What, I can't pass this function as an Http Handler?!

Source: Internet
Author: User
When I help people learn web development, a super-common question is, "Why can't I pass this function into ' http." Handle ' method? It looks with ' http. Handlerfunc ' is exactly the same! "'" Gofunc Demo (H http. Handler) {}func Handler (w http. Responsewriter, R *http. Request) {}func main () {//This line of code will be compiled with an error of demo (handler)} ' > Run the sample code in Go Playground →https://play.golang.org/p/ Jay4rdyqqn3 I can definitely understand their confusion. For one accept ' http. Handlerfunc ' type arguments, we can define an explicit as ' http '. Handlerfunc ' type of variable is passed into it, we can also put a ' func (http. Responsewriter, *http. Request) ' This signature function is passed in as a parameter, so why can't the above code run? To answer this question, we need to delve into the ' HTTP. Handlerfunc ' and ' http. Handler ' type, and we use some sample code to explore their features. us from ' http. Handlerfunc ' Start, it's defined as: ' ' Gotype handlerfunc func (w responsewriter, R *request) ' So we can write this code: "' Gofunc Demo (fn http. Handlerfunc) {}func handler (w http. Responsewriter, R *http. Request) {}func main () {demo (handler)} ' > Run the sample code in Go Playground →HTTPS://PLAY.GOLANG.ORG/P/NDDBOHQPFQH Note that This code is completely different from the top problem code-our ' demo ' function receives the parameter type ' HTTP '. Handlerfunc ', not ' http. Handler '. There is a fact that you may not have found that the ' handler ' in the code is actually not an ' http '. Handlerfunc ', which is the actual type of ' func ' (http. Responsewriter, *http. Request) ', we can reveal this fact by running the following test code. "' Gopackage mainimport (" FMT "" Net/http ") func main () {FMT. Printf ("%T", Handler)}func handler (w http. Responsewriter, R *http. Request) {//handler func implementation content} ' > Run the sample code in Go Playground →https://play.golang.org/p/ep8xlykuodx so, Why would we expect to pass ' handler ' as a parameter to the ' Dmeo ' function in the top problem code? It's obviously different in type! Of course, in our example, our ' handler ' function is fully compliant with ' HTTP '. Handlerfunc ' is defined, so the Go compiler can infer that we want to convert our variables to that type. In other words, the compiler can pretend that our code is written like this: "' Godemo (http. Handlerfunc (Demo)) ' Plus go ' http. The Handlerfunc ' section is derived from the ' demo ' function. Well, now we can take the second step--' http. Handlerfunc ' also implements ' HTTP. Handler ' interface. Why is this, we just need to look at both the source code can be. "' Gotype handlerfunc func (w responsewriter, R *request) func (f Handlerfunc) servehttp (w responsewriter, R *request) {f (W, R)}type Handler interface {servehttp (Responsewriter, *request)} "Please note that ' handlerfunc ' has a ' servehttp ' method that matches the ' Handler ' interface sound This means that ' handlerfunc ' implements the ' Handler ' interface. This may seem strange, but in the Go language it is perfectly valid. After all, ' Handlerfunc ' is another type, and we can add methods to any type at any time. Because ' Handlerfunc ' has achieved ' Handler '' Interface, we can pass ' handlerfunc ' to the function that accepts the ' Handler ' argument, as long as the parameter type is explicitly defined as ' Handlerfunc '. The sample code is as follows: ' ' Gopackage mainimport ' Net/http ' func demo (fn http. Handler) {}func Handler (w http. Responsewriter, R *http. Request) {}func main () {demo (http. Handlerfunc (Handler)} "> Run the Sample code in Go Playground →https://play.golang.org/p/k7sd51wnbl9 now we know ' http. Handlerfunc ' implemented ' HTTP. Handler ' interface, and we know we can type ' func (http. Responsewriter, *http. Request) ' object is passed to a need ' http. Handlerfunc ' type parameter in the function, but why we cannot pass ' func (http. Responsewriter, *http. Request) ' type to a need ' http. Handlerfunc ' type parameters in the function? Or, why is this code not compiled? "' Gofunc Demo (H http. Handler) {}func Handler (w http. Responsewriter, R *http. Request) {}func main () {///This line of code will be compiled with an error of demo (handler)} ' The simple answer is that the compiler does not know how to ' func ' (http. Responsewriter, *http. Request) ' type is converted to ' HTTP '. Handler ' type. To implement such a conversion, the compiler needs to know that we want to convert ' handler ' to ' HTTP '. Handlerfunc ', but in the code above, we don't see ' http at all. Handlerfunc ' this type. If you use the inference rule that we said before, the Go compiler can only assume that the code actually wants to write this: "' Godemo (http. Handler (Handler) "But this is obviously wrong. ' Handler ' does not implement ' HTTP '. HandlEr ' interface, unless it is converted into an ' HTTP ' that implements the interface. Handlerfunc ' type. There is also a way that we do a two-step conversion that will ' Func ' (http. Responsewriter, *http. Request) ' converted to HTTP. Handler: "1 2func, Handlerfunc, Handler" If we explicitly convert the ' Handler ' function to ' http '. Handlerfunc ', then this code is ready to run. "' Gofunc Demo (H http. Handler) {}func Handler (w http. Responsewriter, R *http. Request) {}func main () {//code can be compiled! Demo (http. Handlerfunc (Handler)} "> Run the sample code in Go Playground →https://play.golang.org/p/dm33tpgvonh again, if we assume Go The compiler can pretend that our code is automatically converting incoming parameters into the actual desired type, and the code looks like this: "' Godemo (http. Handler (http. Handlerfunc (handler)) "Well, why does the compiler not learn to automatically do this for us in this two-step, straightforward type conversion? The beginner's explanation is that the compiler doesn't know that the two-step conversion is what you really want to do. Let's assume you have another type, assuming it's called ' Cowboyfunc ', which is defined as follows: ' ' Gotype cowboyfunc func (w http. Responsewriter, R *http. Request) func (f Cowboyfunc) servehttp (w http. Responsewriter, R *http. Request) {s: = time. Now () F (W, R) fmt. Println ("Cowboy function Duration:", time. Now (). Sub (s))} ' Now, if we call ' demo (handler) ' As we did before, then the compiler automatically converts the ' handler ' type to ' http '. Handlerfunc ' type, and then compile successfully, but is this what developers really want to do? In case the developer wants to turn ' handler 'Instead of ' Cowboyfunc '? It also implements the ' HTTP. Handler ' interface. "' Godemo (Cowboyfunc (handler)) ' > Run the sample code in Go Playground →https://play.golang.org/p/tjelwdethyx you can see that this is also a valid code, This means that the compiler does not know exactly which of the two we want, unless we can tell it clearly. All in all, you cannot direct the ' func ' (http. Responsewriter, *http. Request) ' Pass to need ' http. Handler ' type parameter of the function, which may make you feel confused or cumbersome, but can not do so for a reasonable reason, and once you understand these reasons, you may be more grateful to those who appear occasionally, annoying mistakes.

via:https://www.calhoun.io/why-cant-i-pass-this-function-as-an-http-handler/

Author: Jon Calhoun Translator: Moodwu proofreading: polaris1119

This article by GCTT original compilation, go language Chinese network honor launches

This article was originally translated by GCTT and the Go Language Chinese network. Also want to join the ranks of translators, for open source to do some of their own contribution? Welcome to join Gctt!
Translation work and translations are published only for the purpose of learning and communication, translation work in accordance with the provisions of the CC-BY-NC-SA agreement, if our work has violated your interests, please contact us promptly.
Welcome to the CC-BY-NC-SA agreement, please mark and keep the original/translation link and author/translator information in the text.
The article only represents the author's knowledge and views, if there are different points of view, please line up downstairs to spit groove

230 Reads
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.