<p>In astaxie's Build web applications with Golang there's an <a href="https://astaxie.gitbooks.io/build-web-application-with-golang/en/04.1.html" rel="nofollow">example</a> showing a typical "hello world" project that serves a web page. It listens and servers, but I don't really know how. For example, main() contains this code:</p>
<pre><code>func main() {
defer fmt.Println("DONE")
http.HandleFunc("/", sayhelloName)
http.HandleFunc("/login", login)
err := http.ListenAndServe(":9090", nil) // setting listening port
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
</code></pre>
<p>My questions are:</p>
<ul>
<li>Where is the http object declared in main()?</li>
<li>Why isn't my defer executed? I mean, I know it's not supposed to be, but I don't understand the order of execution. If there'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't already, I'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'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't imported. However, as it's an example snippet I'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't exit the program like <code>log.Print</code>. </p>
<p>Fourth, there <em>is</em> a loop going on, but it'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't have objects like you'd find in JavaScript or perhaps Python. The only time you'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't find where anything like ListenAndServe is described. I'll re-review. Thanks for explaining the blocking loop in http.HandleFunc</p></pre>Zikes: <pre><p>I'm on my phone so I can'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 "http"</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't necessarily doing anything until the <code>ListenAndServe</code> is run, before that they'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: "The handler is usually nil, which means to use DefaultServeMux. Handle and HandleFunc add handlers to DefaultServeMux:"</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传