0

0

使用 Go 语言的模板和作用域/函数

心靈之曲

心靈之曲

发布时间:2025-07-13 18:42:21

|

696人浏览过

|

来源于php中文网

原创

使用 go 语言的模板和作用域/函数

本文深入探讨了 Go 语言中模板的使用,特别是 template.FormatterMap 的工作原理,解释了为什么需要包装函数来适配特定的函数签名。同时,还探讨了如何修改 HTTP 处理函数以接受命令行参数,从而提高程序的灵活性和可配置性。

理解 template.FormatterMap 和函数签名

在 Go 语言的 html/template 包中,FormatterMap 类型定义了一个字符串到格式化函数的映射。这些格式化函数用于在模板执行期间处理特定类型的数据。FormatterMap 的定义如下:

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

这意味着 FormatterMap 中的每个值都必须是一个具有 func(io.Writer, interface{}, string) 签名的函数。

现在,考虑 template.HTMLEscape 函数的签名:

func HTMLEscape(w io.Writer, b []byte)

这个函数接受一个 io.Writer 和一个字节切片 []byte 作为参数,并将字节切片进行 HTML 转义后写入 io.Writer。

由于 HTMLEscape 的签名与 FormatterMap 所需的签名不匹配,因此不能直接将 HTMLEscape 函数赋值给 FormatterMap 中的一个键。

这就是为什么需要一个包装函数 UrlHtmlFormatter 的原因。这个包装函数接收 io.Writer、interface{} 和 string 作为参数,并在其内部调用 HTMLEscape 函数。通过这种方式,UrlHtmlFormatter 适配了 FormatterMap 所需的函数签名,同时允许我们使用 HTMLEscape 函数来处理模板中的数据。

以下是 UrlHtmlFormatter 函数的示例:

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

在这个函数中,v.(string) 将 interface{} 类型的值转换为字符串。然后,http.URLEscape 函数对字符串进行 URL 编码,并将结果转换为字节切片。最后,template.HTMLEscape 函数对字节切片进行 HTML 转义,并将结果写入 io.Writer。

修改 HTTP 处理函数以接受命令行参数

原始代码中的 QR 函数接受一个 http.Conn 和一个 http.Request 作为参数:

func QR(c *http.Conn, req *http.Request) {
    templ.Execute(req.FormValue("s"), c)
}

要修改这个函数以接受命令行参数,可以使用 flag 包来定义和解析命令行标志。

SmartB2B行业电子商务
SmartB2B行业电子商务

SmartB2B 是一款基于PHP、MySQL、Smarty的B2B行业电子商务网站管理系统,系统提供了供求模型、企业模型、产品模型、人才招聘模型、资讯模型等模块,适用于想在行业里取得领先地位的企业快速假设B2B网站,可以运行于Linux与Windows等多重服务器环境,安装方便,使用灵活。 系统使用当前流行的PHP语言开发,以MySQL为数据库,采用B/S架构,MVC模式开发。融入了模型化、模板

下载

首先,在 main 函数中定义一个命令行标志:

var text = flag.String("text", "", "Text to encode in QR code")

这个标志名为 text,默认值为空字符串,描述为 "Text to encode in QR code"。

然后,在 main 函数中调用 flag.Parse() 来解析命令行标志:

func main() {
    flag.Parse()
    http.HandleFunc("/", QR) // 使用 http.HandleFunc
    err := http.ListenAndServe(*addr, nil)
    if err != nil {
        log.Fatal("ListenAndServe:", err) // 使用 log.Fatal
    }
}

现在,可以修改 QR 函数以使用命令行标志的值:

func QR(w http.ResponseWriter, req *http.Request) {
    var data string
    if *text != "" {
        data = *text
    } else {
        data = req.FormValue("s")
    }
    templ.Execute(data, w)
}

在这个修改后的 QR 函数中,首先检查命令行标志 text 是否为空。如果不为空,则使用命令行标志的值作为要编码的数据。否则,使用请求参数 s 的值作为要编码的数据。

注意事项:

  • 需要将 QR 函数的签名更改为 func(w http.ResponseWriter, req *http.Request),以便与 http.HandleFunc 兼容。
  • 需要使用 log.Fatal 而不是 log.Exit,以便在发生错误时正确退出程序。
  • 需要使用 http.ResponseWriter 作为 templ.Execute 的第二个参数。

完整代码示例:

package main

import (
    "flag"
    "fmt"
    "html/template"
    "io"
    "log"
    "net/http"
    "net/url"
)

var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
var text = flag.String("text", "", "Text to encode in QR code")
var fmap = template.FuncMap{
    "html":    template.HTMLEscapeString,
    "url+html": UrlHtmlFormatter,
}
var templ = template.Must(template.New("qr").Funcs(fmap).Parse(templateStr))

func main() {
    flag.Parse()
    http.HandleFunc("/", QR)
    fmt.Println("Server listening on", *addr)
    err := http.ListenAndServe(*addr, nil)
    if err != nil {
        log.Fatal("ListenAndServe:", err)
    }
}

func QR(w http.ResponseWriter, req *http.Request) {
    var data string
    if *text != "" {
        data = *text
    } else {
        data = req.FormValue("s")
    }
    err := templ.Execute(w, data)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

func UrlHtmlFormatter(v interface{}) template.HTML {
    escapedURL := url.QueryEscape(fmt.Sprint(v))
    escapedHTML := template.HTMLEscapeString(escapedURL)
    return template.HTML(escapedHTML)
}

const templateStr = `


QR Link Generator


{{if .}}
@@##@@

{{.|html}}

{{end}}
`

总结:

通过理解 template.FormatterMap 的函数签名要求,我们可以创建包装函数来适配不同的函数。此外,使用 flag 包可以轻松地向 Go 程序添加命令行参数,从而提高程序的灵活性和可配置性。

使用 Go 语言的模板和作用域/函数

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

463

2023.08.02

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

320

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1502

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

624

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

653

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

609

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

172

2025.07.29

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号