Implementing dynamic strings in golang

huangapple go评论81阅读模式
英文:

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))

将输入数据准备为structmap的形式:

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.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"))
}
英文:

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"))
}

huangapple
  • 本文由 发表于 2015年3月16日 15:01:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/29071212.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定