在Golang中实现动态字符串

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.

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.

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.

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

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

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))
    t.Execute(os.Stdout, data) // Prints result to the standard output

    // Now change something:
    data["Name"] = "Alice"
    data["ToBring"] = "a Teddy Bear"
    t.Execute(os.Stdout, data)
}

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{}
    t.Execute(&buf, data)
    return buf.String()
}

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