Mystery http object

xuanbao · · 644 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>In astaxie&#39;s Build web applications with Golang there&#39;s an <a href="https://astaxie.gitbooks.io/build-web-application-with-golang/en/04.1.html" rel="nofollow">example</a> showing a typical &#34;hello world&#34; project that serves a web page. It listens and servers, but I don&#39;t really know how. For example, main() contains this code:</p> <pre><code>func main() { defer fmt.Println(&#34;DONE&#34;) http.HandleFunc(&#34;/&#34;, sayhelloName) http.HandleFunc(&#34;/login&#34;, login) err := http.ListenAndServe(&#34;:9090&#34;, nil) // setting listening port if err != nil { log.Fatal(&#34;ListenAndServe: &#34;, err) } } </code></pre> <p>My questions are:</p> <ul> <li>Where is the http object declared in main()?</li> <li>Why isn&#39;t my defer executed? I mean, I know it&#39;s not supposed to be, but I don&#39;t understand the order of execution. If there&#39;s some kind of loop going on with the first call to http.HandleFunc() why is the second call ever executed when I browse to http://localhost:9090/login?</li> </ul> <hr/>**评论:**<br/><br/>elagergren: <pre><p>First off, if you haven&#39;t already, I&#39;d suggest taking <a href="https://tour.golang.org/welcome/1" rel="nofollow">the tour</a>.</p> <p>Second, <code>http</code> is a package, not an object<sup>1.</sup> The snippet you posted is actually invalid Go code, since there&#39;s no <code>package ...</code> statement at the top of the file (try running it in the <a href="https://play.golang.org" rel="nofollow">playground</a> and the <code>http</code> (and <code>fmt</code> and <code>log</code>) packages aren&#39;t imported. However, as it&#39;s an example snippet I&#39;m sure the author assumed the readers would realize this.</p> <p>Third, <code>defer</code> is never called because <code>http.ListenAndServe</code> <em>always</em> returns a non-nil error, which means the branch containing the call to <code>log.Fatal</code> is <em>always</em> entered. Internally, <code>log.Fatal</code> calls <code>os.Exit</code> which immediately exits the program, skipping <code>defer</code>s. If you want <code>defer</code> to run, use a function that doesn&#39;t exit the program like <code>log.Print</code>. </p> <p>Fourth, there <em>is</em> a loop going on, but it&#39;s not in <code>http.HandleFunc</code>. The loop is inside <code>http.ListenAndServe</code> which blocks indefinitely.</p> <hr/> <p>[1]: Strictly speaking, Go doesn&#39;t have objects like you&#39;d find in JavaScript or perhaps Python. The only time you&#39;ll find the <code>foo.bar</code> notation is when accessing the contents of a package (a function, variable, etc.) or when accessing a field of a struct.</p></pre>Hardwareimpaired: <pre><p>Thank you. I reviewed the tour and couldn&#39;t find where anything like ListenAndServe is described. I&#39;ll re-review. Thanks for explaining the blocking loop in http.HandleFunc</p></pre>Zikes: <pre><p>I&#39;m on my phone so I can&#39;t get into too much detail, but</p> <ol> <li><p><code>http</code> is the http library included in the stdlib. As long as you <code>import &#34;http&#34;</code> in the file, it will be available.</p></li> <li><p><code>http.ListenAndServe</code> is the blocking action. It will stop right where it is and continuously listen on the address/port provided. It is listening on behalf of both of the <code>http.HandleFunc</code> methods, and routing incoming traffic accordingly. Those methods aren&#39;t necessarily doing anything until the <code>ListenAndServe</code> is run, before that they&#39;re just setting things up.</p></li> </ol></pre>Hardwareimpaired: <pre><p>Eureka! Now I get it! Thank you. After reading your answer this passage in the <a href="https://golang.org/pkg/net/http/" rel="nofollow">http</a> documentation jumped right out at me: &#34;The handler is usually nil, which means to use DefaultServeMux. Handle and HandleFunc add handlers to DefaultServeMux:&#34;</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

644 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传