在golang中实现动态字符串

4

我有以下的全局字符串:

studentName := "Hi ? ,Welcome"

现在我想动态获取这个字符串。
func returnName(name string) string{
    return studentName+name
}

这个函数应该返回字符串作为
Hi name,welcome.

如何在golang中实现从参数中获取名称并返回动态字符串的功能?


1
如果您没有任何复杂的模板处理要做,我认为fmt.Sprintf是最好的选择。 - Not_a_Golfer
是的,谢谢通知 :) - Akash Shinde
5个回答

13

如果您想保持简单,您可能只需使用fmt.Sprintf

studentName := fmt.Sprintf("Hi, %s! Welcome.", name)

%s 部分将被 name 的值所替换。


1
这是最简单、最明显的解决方案,除非需要复杂的模板,否则没有理由不选择它。OP - Not_a_Golfer

8
如果您的输入变得更大(更复杂)或者您需要多次替换不同的值,那么模板会更加有效、干净和灵活。请查看 text/template 包。 template 包仅解析一次您的模板,从中构建一棵树,在需要替换值时即时地构建输出。
请看下面的示例:
const templ = `Hi {{.Name}}!
Welcome {{.Place}}.
Please bring {{.ToBring}}
`

您可以使用以下代码解析这样的模板:
t := template.Must(template.New("").Parse(templ))

将输入数据准备为structmap

data := map[string]string{
    "Name":    "Bob",
    "Place":   "Home",
    "ToBring": "some beers",
}

你可以通过 Template.Execute() 获取结果:

err := t.Execute(os.Stdout, data) // Prints result to the standard output

这是一个完整的可运行示例:(在Go Playground上尝试)

package main

import (
    "os"
    "text/template"
)

func main() {
    data := map[string]string{
        "Name":    "Bob",
        "Place":   "Home",
        "ToBring": "some beers",
    }
    t := template.Must(template.New("").Parse(templ))
    if err := t.Execute(os.Stdout, data); err != nil { // Prints result to the standard output
        panic(err)
    }

    // Now change something:
    data["Name"] = "Alice"
    data["ToBring"] = "a Teddy Bear"
    if err := t.Execute(os.Stdout, data); err != nil {
        panic(err)
    }
}

const templ = `
Hi {{.Name}}!
Welcome {{.Place}}.
Please bring {{.ToBring}}
`

输出:

Hi Bob!
Welcome Home.
Please bring some beers

Hi Alice!
Welcome Home.
Please bring a Teddy Bear

将结果作为 string 获取:

如果您想要将结果作为 string,您可以将结果写入 bytes.Buffer 并使用 Buffer.String() 方法获取 string

buf := bytes.Buffer{}
t.Execute(&buf, data)
var result string = buf.String()

完整的程序(在Go Playground上试试):

package main

import (
    "bytes"
    "fmt"
    "text/template"
)

func main() {
    data := map[string]string{
        "Name":    "Bob",
        "Place":   "Home",
        "ToBring": "some beers",
    }
    fmt.Print(Execute(data))
}

var t = template.Must(template.New("").Parse(templ))

func Execute(data interface{}) string {
    buf := bytes.Buffer{}
    if err := t.Execute(&buf, data); err != nil {
        fmt.Println("Error:", err)
    }
    return buf.String()
}

const templ = `
Hi {{.Name}}!
Welcome {{.Place}}.
Please bring {{.ToBring}}
`

3

您可以考虑使用函数 strings.Replace

return Replace(studentName, "? ", name, 1)

使用'1',它将替换在studentName中找到的第一个"? "。
Replace返回studentName的副本,并用name替换"? "

这严格遵循原始问题(全局变量具有该精确内容)


现在,如果您开始更改问题,例如使用不同的内容(全局变量studentName := "Hi %s ,Welcome"),那么您可以像425nespanswer中那样使用fmt.Sprintf()。请注意保留HTML标签。
return fmt.Sprintf(studentName, name)

那将使用格式动词%s,字符串的默认格式。

谢谢,这是最简单的解决方案 :) - Akash Shinde

0
假设全局字符串始终相同,您可以这样做。
func returnName(name string) string {
   buf := bytes.Buffer{}
   buf.WriteString("Hi ")
   buf.WriteString(name)
   buf.WriteString(", welcome")
   return buf.String()
}

或者

func returnName(name string) string {
   return "Hi " + name + ", welcome"
}

如果字符串是一个动态模板,你可以使用模板包或者简单的替换(Replace)函数,前提是没有其他的问号标记(?)或者Sprintf函数。

0

您还可以使用template.Templatestrings.Builder组合:

package main

import (
   "strings"
   "text/template"
)

func returnName(name string) string {
   t, b := new(template.Template), new(strings.Builder)
   template.Must(t.Parse("Hi {{.}}, welcome.")).Execute(b, name)
   return b.String()
}

func main() {
   println(returnName("Akash"))
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接