正如之前的小节所说,ChitChat应用会通过HandleFunc
函数把请求重定向到处理器函数。正如代码清单2-2所示,处理器函数实际上就是一个接受ResponseWriter
和Request
指针作为参数的Go函数。
代码清单2-2 main.go文件中的index处理器函数
func index(w http.ResponseWriter, r *http.Request) {
files := []string{
"templates/layout.html",
"templates/navbar.html",
"templates/index.html",
}
templates := template.Must(template.ParseFiles(files...))
threads, err := data.Threads(); if err == nil {
templates.ExecuteTemplate(w, "layout", threads)
}
}
index
函数负责生成HTML并将其写入ResponseWriter
中。因为这个处理器函数会用到html/template
标准库中的Template
结构,所以包含这个函数的文件需要在文件的开头导入html/template
库。之后的小节将对生成HTML的方法做进一步的介绍。
除了前面提到过的负责处理根URL请求的index
处理器函数,main.go
文件实际上还包含很多其他的处理器函数,如代码清单2-3所示。
代码清单2-3 ChitChat应用的main.go源文件
package main
import (
"net/http"
)
func main() {
mux := http.NewServeMux()
files := http.FileServer(http.Dir(config.Static))
mux.Handle("/static/", http.StripPrefix("/static/", files))
mux.HandleFunc("/", index)
mux.HandleFunc("/err", err)
mux.HandleFunc("/login", login)
mux.HandleFunc("/logout", logout)
mux.HandleFunc("/signup", signup)
mux.HandleFunc("/signup_account", signupAccount)
mux.HandleFunc("/authenticate", authenticate)
mux.HandleFunc("/thread/new", newThread)
mux.HandleFunc("/thread/create", createThread)
mux.HandleFunc("/thread/post", postThread)
mux.HandleFunc("/thread/read", readThread)
server := &http.Server{
Addr: "0.0.0.0:8080",
Handler: mux,
}
server.ListenAndServe()
}
main
函数中使用的这些处理器函数并没有在main.go
文件中定义,它们的定义在其他文件里面,具体请参考ChitChat项目的完整源码。
为了在一个文件里面引用另一个文件中定义的函数,诸如PHP、Ruby和Python这样的语言要求用户编写代码去包含(include)被引用函数所在的文件,而另一些语言则要求用户在编译程序时使用特殊的链接(link)命令。
但是对Go语言来说,用户只需要把位于相同目录下的所有文件都设置成同一个包,那么这些文件就会与包中的其他文件分享彼此的定义。又或者,用户也可以把文件放到其他独立的包里面,然后通过导入(import)这些包来使用它们。比如,ChitChat论坛就把连接数据库的代码放到了独立的包里面,我们很快就会看到这一点。