英文:
Google's 'go' and scope/functions
问题
在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
...提前谢谢...
英文:
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...
答案1
得分: 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))))
}
英文:
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))))
}
答案2
得分: 0
你编辑了原始问题以添加这个第二个问题。
> 另外,我如何将func QR更改为接受参数值?我希望它能够接受一个命令行标志,而不是req *http.Request。
如果你阅读Go编程语言规范中的类型部分,包括函数类型部分,你会发现Go具有强大的静态类型,包括函数类型。虽然这不能保证捕捉到所有错误,但通常可以捕捉到使用无效或不匹配的函数签名的尝试。
你没有告诉我们为什么要以任意和武断的方式更改QR
函数的签名,使其不再是有效的HandlerFunc
类型,从而保证程序甚至无法编译通过。我们只能猜测你想要实现什么。也许很简单,你想根据运行时参数修改http.Request
。也许是这样的:
// 注意:在func main() {...}中调用flag.Parse()
var qrFlag = flag.String("qr", "", "function QR parameter")
func QR(c *http.Conn, req *http.Request) {
if len(*qrFlag) > 0 {
// 在这里插入代码,使用qr参数(qrFlag)修改http.Request(req)
}
templ.Execute(req.FormValue("s"), c)
}
也许不是!谁知道呢?
英文:
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?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论