英文:
Implementing dynamic strings in golang
问题
我有以下全局字符串:
studentName := "Hi ? ,Welcome"
现在我想动态地获取这个字符串:
func returnName(name string) string{
return studentName+name
}
这个函数应该返回以下字符串:
Hi name,welcome.
字符串应该从参数中获取name,并返回动态字符串。在Go语言中,最佳的实现方式是什么?
英文:
I have following global string,
studentName := "Hi ? ,Welcome"
Now I want to take this string dynamically
func returnName(name string) string{
return studentName+name
}
This function should return string as
Hi name,welcome.
string should take name from parameter,and return dynamic string.What is the best way to implement this in golang.
答案1
得分: 13
如果你想保持简单,你可以直接使用fmt.Sprintf。
studentName := fmt.Sprintf("Hi, %s! Welcome.", name)
%s部分将会被name的值替换。
英文:
If you want to keep things simple, you can probably just use fmt.Sprintf.
studentName := fmt.Sprintf("Hi, %s! Welcome.", name)
The %s part will get replaced by the value of name.
答案2
得分: 8
如果您的输入变得更大(更复杂),或者您需要多次替换不同的值,那么模板更有效、更清晰和更灵活。请查看text/template包。
template包会解析您的模板一次,构建一个树形结构,然后在需要替换值时即时构建输出。
看看这个例子:
const templ = `Hi {{.Name}}!
Welcome {{.Place}}.
Please bring {{.ToBring}}
`
您可以使用以下代码解析这样的模板:
t := template.Must(template.New("").Parse(templ))
将输入数据准备为struct或map的形式:
data := map[string]string{
"Name": "Bob",
"Place": "Home",
"ToBring": "some beers",
}
然后,您可以使用Template.Execute()来获取结果:
err := t.Execute(os.Stdout, data) // 将结果打印到标准输出
这是完整可运行的示例:(在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 { // 将结果打印到标准输出
panic(err)
}
// 现在更改一些内容:
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}}
`
英文:
If your input gets bigger (more complex) or if you need to substitute different values multiple times, then templates are more effective, cleaner and more flexible. Check out the text/template package.
The template package parses your template once, builts a tree from it, and once you need to replace values, it builds the output on the fly.
Take a look at this example:
const templ = `Hi {{.Name}}!
Welcome {{.Place}}.
Please bring {{.ToBring}}
`
You can parse such a template with this line:
t := template.Must(template.New("").Parse(templ))
Prepare its input data either as a struct or as a map:
data := map[string]string{
"Name": "Bob",
"Place": "Home",
"ToBring": "some beers",
}
And you can have the result with Template.Execute():
err := t.Execute(os.Stdout, data) // Prints result to the standard output
Here's the complete, runnable example: (try it on the 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}}
`
Output:
Hi Bob!
Welcome Home.
Please bring some beers
Hi Alice!
Welcome Home.
Please bring a Teddy Bear
Getting the result as a string:
If you want the result as a string, you can write the result to a bytes.Buffer and get the string using the Buffer.String() method:
buf := bytes.Buffer{}
t.Execute(&buf, data)
var result string = buf.String()
Complete program (try it on the 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
得分: 3
你可以考虑使用函数strings.Replace。
return Replace(studentName, "? ", name, 1)
使用'1',它会替换studentName中找到的第一个"? "。
Replace函数返回一个将studentName中的"? "替换为name的副本。
这严格遵守原始问题(具有完全相同内容的全局变量)。
现在,如果你开始改变问题,例如使用不同的内容(一个全局变量studentName := "Hi %s, Welcome"),那么你可以使用fmt.Sprintf(),就像425nesp的答案中所示。
return fmt.Sprintf(studentName, name)
这将使用格式化动词%s,它是字符串的默认格式。
英文:
You could consider the function strings.Replace
return Replace(studentName, "? ", name, 1)
With '1', it replaces the first "? " it finds in studentName.
Replace returns a copy of studentName, with "? " substituted with name.
This strictly respect the original question (global var with that exact content)
Now, if you start changing the question, like for instance with a different content (a global variable studentName := "Hi %s ,Welcome"), then you could use fmt.Sprintf() as in 425nesp's answer
return fmt.Sprintf(studentName, name)
That would use the format 'verbs' %s, default format for string.
答案4
得分: 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函数。
英文:
Assuming the global string is always the same you could do.
func returnName(name string) string {
buf := bytes.Buffer{}
buf.WriteString("Hi ")
buf.WriteString(name)
buf.WriteString(", welcome")
return buf.String()
}
or
func returnName(name string) string {
return "Hi " + name + ", welcome"
}
if the string is a dynamic template you could use the template package or a simple Replace if there wont be other ? marks or Sprintf
答案5
得分: 0
你也可以使用template.Template与strings.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"))
}
英文:
You can also use template.Template
combined with strings.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"))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论