谷歌的'去'和范围/功能

时间:2010-03-18 01:56:16

标签: function scope go

在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>
`  

为什么template.HTMLEscape(w, []byte(http.URLEscape(v.(string))))中包含UrlHtmlFormatter?为何不能直接与"url+html"相关联?

另外,如何更改func QR以接受参数值?我想要它做的是接受命令行标志代替req *http.Request ...提前致谢...

2 个答案:

答案 0 :(得分:1)

函数template.HTMLEscape的签名是:

func(w io.Writer, s []byte)

template.FormatterMap的类型声明是:

type FormatterMap map[string]func(io.Writer, interface{}, string)

因此,FormatterMap地图元素值函数的签名是:

func(io.Writer, interface{}, string)

UrlHtmlFormatter函数是一个包装器,为HTMLEscape函数提供FormatterMap映射元素值函数签名。

func UrlHtmlFormatter(w io.Writer, v interface{}, fmt string) {
    template.HTMLEscape(w, []byte(http.URLEscape(v.(string))))
}

答案 1 :(得分:0)

您修改了原始问题以添加第二个问题。

  

另外,我怎么能改变功能QR到   接受参数值?我想要什么   它要做的是接受一个命令行   标志代替req * http.Request。

如果您阅读The Go Programming Language Specification§Types,包括§Function types,您会看到Go具有强大的静态类型,包括函数类型。虽然这并不能保证捕获所有错误,但它通常会捕获使用无效,不匹配的函数签名的尝试。

您没有告诉我们您为什么要更改QR的功能签名,这似乎是一种任意且反复无常的方式,因此它不再是有效的HandlerFunc类型,保证程序甚至无法编译。我们只能猜到你想要完成的事情。也许它就像这样简单:你想根据运行时参数修改http.Request。也许,这样的事情:

// 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)
}

也许不是!谁知道?