开发者

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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜