在Python中,您可以执行以下操作:
"File {file} had error {error}".format(file=myfile, error=err)
或这个:
"File %(file)s had error %(error)s" % {"file": myfile, "error": err}
在Go中,最简单的选项是:
fmt.Sprintf("File %s had error %s", myfile, err)
这不允许您交换格式字符串中参数的顺序,而这需要对I18N进行。Go
确实 具有该template
软件包,这将需要以下内容:
package main
import (
"bytes"
"text/template"
"os"
)
func main() {
type Params struct {
File string
Error string
}
var msg bytes.Buffer
params := &Params{
File: "abc",
Error: "def",
}
tmpl, _ := template.New("errmsg").Parse("File {{.File}} has error {{.Error}}")
tmpl.Execute(&msg, params)
msg.WriteTo(os.Stdout)
}
这似乎是一条很长的路要走的错误消息。有没有更合理的选择,可以让我给出与顺序无关的字符串参数?
strings.Replacer
使用strings.Replacer
,实现您所需的格式化程序非常容易且紧凑。
func main() {
file, err := "/data/test.txt", "file not found"
log("File {file} had error {error}", "{file}", file, "{error}", err)
}
func log(format string, args ...string) {
r := strings.NewReplacer(args...)
fmt.Println(r.Replace(format))
}
输出(在Go Playground上尝试):
File /data/test.txt had error file not found
通过在log()
函数中自动在参数名称中添加方括号,可以使使用起来更加愉快:
func main() {
file, err := "/data/test.txt", "file not found"
log2("File {file} had error {error}", "file", file, "error", err)
}
func log2(format string, args ...string) {
for i, v := range args {
if i%2 == 0 {
args[i] = "{" + v + "}"
}
}
r := strings.NewReplacer(args...)
fmt.Println(r.Replace(format))
}
输出(在Go Playground上尝试):
File /data/test.txt had error file not found
是的,您可以说这仅接受string
参数值。这是真的。有了更多的改进,这将不是真的:
func main() {
file, err := "/data/test.txt", 666
log3("File {file} had error {error}", "file", file, "error", err)
}
func log3(format string, args ...interface{}) {
args2 := make([]string, len(args))
for i, v := range args {
if i%2 == 0 {
args2[i] = fmt.Sprintf("{%v}", v)
} else {
args2[i] = fmt.Sprint(v)
}
}
r := strings.NewReplacer(args2...)
fmt.Println(r.Replace(format))
}
输出(在Go Playground上尝试):
File /data/test.txt had error 666
此方法的一种变体,接受params作为a map[string]interface{}
并以a形式返回结果string
:
type P map[string]interface{}
func main() {
file, err := "/data/test.txt", 666
s := log33("File {file} had error {error}", P{"file": file, "error": err})
fmt.Println(s)
}
func log33(format string, p P) string {
args, i := make([]string, len(p)*2), 0
for k, v := range p {
args[i] = "{" + k + "}"
args[i+1] = fmt.Sprint(v)
i += 2
}
return strings.NewReplacer(args...).Replace(format)
}
在Go Playground上尝试一下。
text/template
您的模板解决方案或建议也太冗长。可以这样紧凑地编写(省略错误检查):
type P map[string]interface{}
func main() {
file, err := "/data/test.txt", 666
log4("File {{.file}} has error {{.error}}", P{"file": file, "error": err})
}
func log4(format string, p P) {
t := template.Must(template.New("").Parse(format))
t.Execute(os.Stdout, p)
}
输出(在Go Playground上尝试):
File /data/test.txt has error 666
如果要返回string
(而不是将其打印到标准输出),则可以这样做(在Go
Playground
上尝试):
func log5(format string, p P) string {
b := &bytes.Buffer{}
template.Must(template.New("").Parse(format)).Execute(b, p)
return b.String()
}
在另一个答案中已经提到了这一点,但是要完成此操作,请知道相同的显式参数索引可以任意使用多次,从而导致同一参数被多次替换。
问题内容: MySQL中的varchar(max)等价于什么? 问题答案: varchar的最大长度取决于MySQL中的最大行大小,即64KB(不包括BLOB): 但是,请注意,如果使用多字节字符集,则限制会更低: 这里有些例子: 最大行大小为65535,但是varchar还包括一个或两个字节来编码给定字符串的长度。因此,即使它是表中的唯一列,您实际上也无法声明最大行大小的varchar。 但是,
问题内容: 在Java中最接近std :: vector的东西是什么?我的意思是,一个可以将T放入其构造函数中,然后将pushBack和popBack()接收到的类,该类存储在连续内存中(而不是链表)。 谢谢 问题答案: ArrayList 一切都内部存储在数组(“连续内存”)中,尽管操作名称略有不同。 有关Java中的列表实现 和泛型的更多信息 编辑 Helper Method 在他的回答中也提
问题内容: 我正在使用Django 1.9,并且正在尝试获取用于从models.py创建数据库表的SQL。 似乎在早期版本的Django中,可以做到: 但这似乎不再是事实了。我得到。文档中似乎没有提供此功能。 如何查看将模型转换为SQL的方式? 问题答案: 据弃用在Django 1.9 : 无需迁移的应用程序的SQL管理命令,sql,sqlall,sqlclear,sqldropindexes和s
问题内容: 我正在努力寻找一种方法,以根据谓词在流的开头跳过某些元素。 像这样: 那相当于Scala 。 问题答案: 这种操作不是s 的预期用例,因为它并入了元素之间的依赖关系。因此,该解决方案可能看起来不太好,因为您必须为谓词引入一个全状态变量: 请注意,与您的示例相比,该条件必须颠倒。 当然,您可以在方法中隐藏令人讨厌的细节: 一个更复杂,但更清洁,可能更有效的方法是深入研究金属,即界面: 可
问题内容: 在Python 2.x中,当您要将一个方法标记为抽象时,可以这样定义它: 然后,如果您忘记覆盖它,则会收到一个很好的提醒异常。是否存在将字段标记为抽象的等效方法?还是在您可以做的所有工作中在类文档字符串中说明? 起初我以为可以将字段设置为NotImplemented,但是当我查看它的实际用途(进行大量比较)时,它似乎很脏。 问题答案: 是的你可以。使用装饰器。例如,如果您有一个名为“e
问题内容: Click中的可选参数是否具有等效于的功能? 我正在编写命令行脚本,并且其中一个选项需要能够接受无限数量的参数,例如: 所以会和会。 在中,我可以指定多个可选参数来通过设置来收集所有跟随它们的参数。 我知道Click允许您通过设置来指定接受无限输入的参数,但是当我尝试将可选参数设置为-1时,我得到: TypeError:选项的nargs不能小于0 有没有一种方法可以使Click接受选项