一尘不染

如何忽略fmt.Sprintf的其他字段

go

我有一个Golang程序,该程序从命令行读取字符串参数,并将其传递给fmt.Sprintf函数。假设tmp_str是命令行中的目标字符串。

package main

import "fmt"

func main() {
    tmp_str := "hello %s"
    str := fmt.Sprintf(tmp_str, "world")
    fmt.Println(str)
}

在某些情况下,该程序将传递完整的字符串,例如“ Hello Friends”,而不是字符串模板。.程序会惊慌并返回:

你好朋友%!(EXTRA string = world)

因此,如何忽略fmt.Sprintf的额外字段?


阅读 284

收藏
2020-07-02

共1个答案

一尘不染

是的,您可以通过切片传递给可变参数Sprintf函数的参数来做到这一点:

func TruncatingSprintf(str string, args ...interface{}) (string, error) {
    n := strings.Count(str, "%s")
    if n > len(args) {
        return "", errors.New("Unexpected string:" + str)
    }
    return fmt.Sprintf(str, args[:n]...), nil
}

func main() {
    tmp_str := "hello %s %s %s"         // don't hesitate to add many %s here
    str, err := TruncatingSprintf(tmp_str, "world") // or many arguments here
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(str)
}

示范1

演示2 (即使%s大于参数,也会输出不同的版本)

但是您通常不使用动态格式的字符串,这是不安全的,并且如果您想接受 任何
字符串,则还应该使此代码适应于您的需求%%s。如果您走了这么远,那么您可能应该看看模板(它可以让您使用命名字符串,因此丢失的一个不必是最后一个)。

2020-07-02