Google's 'go' and scope/functions
In one of the example servers given at golang.org:
package main
import (
"flag"
"http"
"io"
"log"
"template"
)
var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
var fmap = template.FormatterMap{
"html": template.HTMLFormatter,
"url+html": UrlHtmlFormatter,
}
var templ = template.MustParse(templateStr, fmap)
func main() {
flag.Parse()
http.Handle("/", http.HandlerFunc(QR))
err := http.ListenAndServe(*addr, nil)
if err != nil {
log.Exit("ListenAndServe:", err)
}
}
func QR(c开发者_运维百科 *http.Conn, req *http.Request) {
templ.Execute(req.FormValue("s"), c)
}
func UrlHtmlFormatter(w io.Writer, v interface{}, fmt string) {
template.HTMLEscape(w, []byte(http.URLEscape(v.(string))))
}
const templateStr = `
<html>
<head>
<title>QR Link Generator</title>
</head>
<body>
{.section @}
<img src="http://chart.apis.google.com/chart?chs=300x300&cht=qr&choe=UTF- 8&chl={@|url+html}"
/>
<br>
{@|html}
<br>
<br>
{.end}
<form action="/" name=f method="GET"><input maxLength=1024 size=70
name=s value="" title="Text to QR Encode"><input type=submit
value="Show QR" name=qr>
</form>
</body>
</html>
`
Why is template.HTMLEscape(w, []byte(http.URLEscape(v.(string))))
contained within UrlHtmlFormatter
? Why can't it be directly linked to "url+html"
?
Also, how could I change func QR to accept parameter values? What I'd like for it to do is accept a command-line flag in place of req *http.Request
... Thanks in advance...
The signature for function template.HTMLEscape
is:
func(w io.Writer, s []byte)
The type declaration for template.FormatterMap
is:
type FormatterMap map[string]func(io.Writer, interface{}, string)
Therefore, the signature for a FormatterMap
map element value function is:
func(io.Writer, interface{}, string)
The UrlHtmlFormatter
function is a wrapper to give the HTMLEscape
function the FormatterMap
map element value function signature.
func UrlHtmlFormatter(w io.Writer, v interface{}, fmt string) {
template.HTMLEscape(w, []byte(http.URLEscape(v.(string))))
}
You edited your original question to add this second question.
Also, how could I change func QR to accept parameter values? What I'd like for it to do is accept a command-line flag in place of req *http.Request.
If you read The Go Programming Language Specification, §Types, including §Function types, you will see that Go has strong static typing, including function types. While this does not guarantee to catch all errors, it usually catches attempts to use invalid, non-matching function signatures.
You don't tell us why you want to change the function signature for QR
, in what appears to be an arbitrary and capricious fashion, so that it is no longer a valid HandlerFunc
type, guaranteeing that the program will fail to even compile. We can only guess what you want to accomplish. Perhaps it's as simple as this: you want to modify the http.Request
, based on a runtime parameter. Perhaps, something like this:
// Note: flag.Parse() in func main() {...}
var qrFlag = flag.String("qr", "", "function QR parameter")
func QR(c *http.Conn, req *http.Request) {
if len(*qrFlag) > 0 {
// insert code here to use the qr parameter (qrFlag)
// to modify the http.Request (req)
}
templ.Execute(req.FormValue("s"), c)
}
Perhaps not! Who knows?
精彩评论