How to print struct variables in console? - struct

How can I print (to the console) the Id, Title, Name, etc. of this struct in Golang?
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
Data Data `json:"data"`
Commits Commits `json:"commits"`
}

To print the name of the fields in a struct:
fmt.Printf("%+v\n", yourProject)
From the fmt package:
when printing structs, the plus flag (%+v) adds field names
That supposes you have an instance of Project (in 'yourProject')
The article JSON and Go will give more details on how to retrieve the values from a JSON struct.
This Go by example page provides another technique:
type Response2 struct {
Page int `json:"page"`
Fruits []string `json:"fruits"`
}
res2D := &Response2{
Page: 1,
Fruits: []string{"apple", "peach", "pear"}}
res2B, _ := json.Marshal(res2D)
fmt.Println(string(res2B))
That would print:
{"page":1,"fruits":["apple","peach","pear"]}
If you don't have any instance, then you need to use reflection to display the name of the field of a given struct, as in this example.
type T struct {
A int
B string
}
t := T{23, "skidoo"}
s := reflect.ValueOf(&t).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
fmt.Printf("%d: %s %s = %v\n", i,
typeOfT.Field(i).Name, f.Type(), f.Interface())
}

I want to recommend go-spew, which according to their github "Implements a deep pretty printer for Go data structures to aid in debugging"
go get -u github.com/davecgh/go-spew/spew
usage example:
package main
import (
"github.com/davecgh/go-spew/spew"
)
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
Data string `json:"data"`
Commits string `json:"commits"`
}
func main() {
o := Project{Name: "hello", Title: "world"}
spew.Dump(o)
}
output:
(main.Project) {
Id: (int64) 0,
Title: (string) (len=5) "world",
Name: (string) (len=5) "hello",
Data: (string) "",
Commits: (string) ""
}

my 2cents would be to use json.MarshalIndent -- surprised this isn't suggested, as it is the most straightforward. for example:
func prettyPrint(i interface{}) string {
s, _ := json.MarshalIndent(i, "", "\t")
return string(s)
}
no external deps and results in nicely formatted output.

I think it would be better to implement a custom stringer if you want some kind of formatted output of a struct
for example
package main
import "fmt"
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
}
func (p Project) String() string {
return fmt.Sprintf("{Id:%d, Title:%s, Name:%s}", p.Id, p.Title, p.Name)
}
func main() {
o := Project{Id: 4, Name: "hello", Title: "world"}
fmt.Printf("%+v\n", o)
}

p = Project{...}
fmt.Printf("%+v", p)
fmt.Printf("%#v", p) //with type

Alternatively, try using this function PrettyPrint()
// print the contents of the obj
func PrettyPrint(data interface{}) {
var p []byte
// var err := error
p, err := json.MarshalIndent(data, "", "\t")
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%s \n", p)
}
In order to use this you do not need any additional packages with the exception of fmt and encoding/json, just a reference, pointer to, or literal of the struct you have created.
To use just take your struct, initialize it in main or whatever package you are in and pass it into PrettyPrint().
type Prefix struct {
Network string
Mask int
}
func valueStruct() {
// struct as a value
var nw Prefix
nw.Network = "10.1.1.0"
nw.Mask = 24
fmt.Println("### struct as a pointer ###")
PrettyPrint(&nw)
}
It's output would be
### struct as a pointer ###
{
"Network": "10.1.1.0",
"Mask": 24
}
Play around with the code here.

It is very convenient to use package fmt to output:
fmt.Printf("%+v \n", yourProject)
if you want to see the full type of the sturct, you can use # replace + :
fmt.Printf("%#v \n", yourProject)

I recommend to use Pretty Printer Library. In that you can print any struct very easily.
Install Library
https://github.com/kr/pretty
or
go get github.com/kr/pretty
Now do like this in your code
package main
import (
fmt
github.com/kr/pretty
)
func main(){
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
Data Data `json:"data"`
Commits Commits `json:"commits"`
}
fmt.Printf("%# v", pretty.Formatter(Project)) //It will print all struct details
fmt.Printf("%# v", pretty.Formatter(Project.Id)) //It will print component one by one.
}
Also you can get difference between component through this library and so more. You can also have a look on library Docs here.

I like litter.
From their readme:
type Person struct {
Name string
Age int
Parent *Person
}
litter.Dump(Person{
Name: "Bob",
Age: 20,
Parent: &Person{
Name: "Jane",
Age: 50,
},
})
Sdump is pretty handy in tests:
func TestSearch(t *testing.T) {
result := DoSearch()
actual := litterOpts.Sdump(result)
expected, err := ioutil.ReadFile("testdata.txt")
if err != nil {
// First run, write test data since it doesn't exist
if !os.IsNotExist(err) {
t.Error(err)
}
ioutil.Write("testdata.txt", actual, 0644)
actual = expected
}
if expected != actual {
t.Errorf("Expected %s, got %s", expected, actual)
}
}

To print the struct as JSON:
fmt.Printf("%#v\n", yourProject)
Also possible with (as it was mentioned above):
fmt.Printf("%+v\n", yourProject)
But the second option prints string values without "" so it is harder to read.

I suggest u use fmt.Printf("%#v\n", s) , It will print golang type at the same time
package main
import (
"fmt"
"testing"
)
type student struct {
id int32
name string
}
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
}
func TestPrint(t *testing.T) {
s := Project{1, "title","jack"}
fmt.Printf("%+v\n", s)
fmt.Printf("%#v\n", s)
}
result:
{Id:1 Title:title Name:jack}
main.Project{Id:1, Title:"title", Name:"jack"}

You can do the json mashal first and print it as a string. There you can see it the whole struct value completely.
package main
import "fmt"
import "json"
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
}
func main() {
o := Project{Id: 4, Name: "hello", Title: "world"}
om, _ := json.marshal(o)
log.Printf("%s\n", string(om))
}

When you have more complex structures, you might need to convert to JSON before printing:
// Convert structs to JSON.
data, err := json.Marshal(myComplexStruct)
fmt.Printf("%s\n", data)
Source: https://gist.github.com/tetsuok/4942960

Sometimes, it might be handy to print the struct as valid Go code (the go/ast equivalent). For this purpose, https://github.com/hexops/valast does a great job:
package main
import (
"fmt"
"github.com/hexops/valast"
)
type ProjectData struct {
Title string `json:"title"`
Name string `json:"name"`
Data string `json:"data"`
Commits string `json:"commits"`
}
type Project struct {
Id int64 `json:"project_id"`
Data *ProjectData `json:"data"`
}
func main() {
p := Project{
Id: 1,
Data: &ProjectData{
Title: "Test",
Name: "Mihai",
Data: "Some data",
Commits: "Test Message",
},
}
fmt.Println(valast.String(p))
}
Output:
go run main.go
Project{Id: 1, Data: &ProjectData{
Title: "Test",
Name: "Mihai",
Data: "Some data",
Commits: "Test Message",
}}

Visit here to see the complete code. Here you will also find a link for an online terminal where the complete code can be run and the program represents how to extract structure's information(field's name their type & value). Below is the program snippet that only prints the field names.
package main
import "fmt"
import "reflect"
func main() {
type Book struct {
Id int
Name string
Title string
}
book := Book{1, "Let us C", "Enjoy programming with practice"}
e := reflect.ValueOf(&book).Elem()
for i := 0; i < e.NumField(); i++ {
fieldName := e.Type().Field(i).Name
fmt.Printf("%v\n", fieldName)
}
}
/*
Id
Name
Title
*/

Maybe this shouldn't be applied for production requests but if you are on debugging mode I suggest you follow the below approach.
marshalledText, _ := json.MarshalIndent(inputStruct, "", " ")
fmt.Println(string(marshalledText))
This results in formatting the data in json format with increased readability.

i suggest to use json.Unmarshal()
i try to print the id with this hope its helpfull:
var jsonString = `{"Id": 1, "Title": "the title", "Name": "the name","Data": "the data","Commits" : "the commits"}`
var jsonData = []byte(jsonString)
var data Project
var err = json.Unmarshal(jsonData, &data)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println("Id :", data.Id)

There's also go-render, which handles pointer recursion and lots of key sorting for string and int maps.
Installation:
go get github.com/luci/go-render/render
Example:
type customType int
type testStruct struct {
S string
V *map[string]int
I interface{}
}
a := testStruct{
S: "hello",
V: &map[string]int{"foo": 0, "bar": 1},
I: customType(42),
}
fmt.Println("Render test:")
fmt.Printf("fmt.Printf: %#v\n", a)))
fmt.Printf("render.Render: %s\n", Render(a))
Which prints:
fmt.Printf: render.testStruct{S:"hello", V:(*map[string]int)(0x600dd065), I:42}
render.Render: render.testStruct{S:"hello", V:(*map[string]int){"bar":1, "foo":0}, I:render.customType(42)}

fmt.Printf("%+v\n", project)
This is the basic way of printing the details

You don't even need the verb. This dumps everything inside of data:
fmt.Println(data)

very simple
I don't have the structure of Data and Commits So I changed the
package main
import (
"fmt"
)
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
Data string `json:"data"`
Commits string `json:"commits"`
}
func main() {
p := Project{
1,
"First",
"Ankit",
"your data",
"Commit message",
}
fmt.Println(p)
}
For learning you can take help from here : https://gobyexample.com/structs

If you want to write in a log file, as I was searching previously. Then you should use:
log.Infof("Information %+v", structure)
Note:: This will not work with log.Info or log.Debug. In this case, "%v" will get printed, and all the values of the structure will be printed without printing the key/variable name.

A lot of answers for a simple question. I might as well throw my hat in the ring.
package main
import "fmt"
type Project struct {
Id int64 `json:"project_id"`
Title string `json:"title"`
Name string `json:"name"`
//Data Data `json:"data"`
//Commits Commits `json:"commits"`
}
var (
Testy Project
)
func dump_project(foo Project) {
fmt.Println("== Dump Project Struct ====")
fmt.Printf("Id: %d\n", foo.Id)
fmt.Println("Title: ", foo.Title)
fmt.Printf("Name: %v\n", foo.Name)
}
func main() {
fmt.Println("hello from go")
Testy.Id = 3
Testy.Title = "yo"
Testy.Name = "my name"
fmt.Println(Testy)
dump_project(Testy)
}
The output of the various print methods
hello from go
{3 yo my name}
== Dump Project Struct ====
Id: 3
Title: yo
Name: my name

Without using external libraries and with new line after each field:
log.Println(
strings.Replace(
fmt.Sprintf("%#v", post), ", ", "\n", -1))

type Response struct {
UserId int `json:"userId"`
Id int `json:"id"`
Title string `json:"title"`
Body string `json:"body"`
}
func PostsGet() gin.HandlerFunc {
return func(c *gin.Context) {
xs, err := http.Get("https://jsonplaceholder.typicode.com/posts")
if err != nil {
log.Println("The HTTP request failed with error: ", err)
}
data, _ := ioutil.ReadAll(xs`enter code here`.Body)
// this will print the struct in console
fmt.Println(string(data))
// this is to send as response for the API
bytes := []byte(string(data))
var res []Response
json.Unmarshal(bytes, &res)
c.JSON(http.StatusOK, res)
}
}

Another way is, create a func called toString that takes struct, format the
fields as you wish.
import (
"fmt"
)
type T struct {
x, y string
}
func (r T) toString() string {
return "Formate as u need :" + r.x + r.y
}
func main() {
r1 := T{"csa", "ac"}
fmt.Println("toStringed : ", r1.toString())
}

Most of these packages are relying on the reflect package to make such things possible.
fmt.Sprintf() is using -> func (p *pp) printArg(arg interface{}, verb rune) of standard lib
Go to line 638 -> https://golang.org/src/fmt/print.go
Reflection:
https://golang.org/pkg/reflect/
Example code:
https://github.com/donutloop/toolkit/blob/master/debugutil/prettysprint.go

fmt.Println("%+v", structure variable)
A better way to do this would be to create a global constant for the string "%+v" in a package called "commons"(maybe) and use it everywhere in your code
//In commons package
const STRUCTURE_DATA_FMT = "%+v"
//In your code everywhere
fmt.Println(commons.STRUCTURE_DATA_FMT, structure variable)

Related

Best practice to use the same function with different structs - Golang

So let's say that I have different structs, which have common fields, and I want to use the same toString method for both.
Because the logic and the flow will be exactly the same. And I don't want to duplicate it. I'm thinking about what can be done about this.
type mobile struct {
"version" string,
"appName" string
}
type other struct {
"release" string,
"app_name" string
}
So let's say I have these two structs. Actually, the version holds the same meaning as the release. And mobile > appName and other> app_name again holds the same meaning.
So I want to write one toString method where I can list the details of these two objects.
func detailsOfMobile(app mobile) string {
message := fmt.Sprintf("Here is the details of the *%s* with the version %s", app.appName, app.version)
.....
return message
}
so for other I need to duplicate it;
func detailsOfOther (app Ipad) string {
message := fmt.Sprintf("Here is the details of the *%s* with the version %s", app.app_name, app.release)
.....
return message
}
Actually the methods are much more complicated in reality. But what I'm trying to stay here, both structs have common fields, but they are named differently. What can be the best practice here not to duplicate the code?
You have two choices, the closest way of doing what you are literally asking is to use an interface. Your function accepts a common interface and your structs both implement it:
package main
import (
"fmt"
)
type App interface {
Name() string
Version() string
}
type mobile struct {
version string
appName string
}
func (m mobile) Name() string { return m.appName }
func (m mobile) Version() string { return m.version }
type other struct {
release string
app_name string
}
func (o other) Name() string { return o.app_name }
func (o other) Version() string { return o.release }
func detailsOfMobile(a App) string {
message := fmt.Sprintf("Here is the details of the *%s* with the version %s", a.Name(), a.Version())
return message
}
func main() {
fmt.Println(detailsOfMobile(mobile{version: "1", appName: "iDaft"}))
fmt.Println(detailsOfMobile(other{release: "2", app_name: "Shazam"}))
}
// Here is the details of the *iDaft* with the version 1
// Here is the details of the *Shazam* with the version 2
As a simpler approach, you could also just make both structs implement the well known Stringer interface:
package main
import (
"fmt"
)
type mobile struct {
version string
appName string
}
func (m mobile) String() string {
return fmt.Sprintf("%s version %s", m.appName, m.version)
}
type other struct {
release string
app_name string
}
func (o other) String() string {
return fmt.Sprintf("%s release %s", o.app_name, o.release)
}
func main() {
fmt.Println(mobile{version: "1", appName: "iDaft"})
fmt.Println(other{release: "2", app_name: "Shazam"})
}
// iDaft version 1
// Shazam release 2

Print list of fields in struct with delimiter

I have a type with three fields
type Person struct {
FirstName string
LastName string
Age int
}
Creating an instance and using default fmt.Sprint() returns {John Smith 45}. However for my use case I need a string of format John, Smith, 45. A comma delimited list without being surrounded by curly braces. Is there a more reusable and effective way than:
fmt.Sprintf("%s, %s, %d", x.FirstName, x.LastName, x.Age)
I will be using this method alot with other types and I would prefer a generic method rather than having to type out a format for each type I use:
func asFields(data interface{}) string {
// TODO logic here
}
That exact format is not supported by verbs of the fmt package.
The closest would be
s := fmt.Sprintf("%#v", p)
Which generates a string like:
main.Person{FirstName:"John", LastName:"Smith", Age:45}
If you exactly need what you posted in the question, you may use reflection to iterate over the fields and build the result like this:
func asFields(data interface{}) string {
v := reflect.ValueOf(data)
b := &strings.Builder{}
for i := 0; i < v.NumField(); i++ {
if i > 0 {
b.WriteString(", ")
}
b.WriteString(fmt.Sprint(v.Field(i).Interface()))
}
return b.String()
}
This indeed gives:
John, Smith, 45
Try the examples on the Go Playground.
Note that this asFields() function handles all struct types of course not just your Person. Adjustment would be needed to handle pointers and struct of structs of course.
Also note that alternatively to fmt.Sprint() you may also use fmt.Fprint() directed to the buffer in which we're assembling the string:
func asFields(data interface{}) string {
v := reflect.ValueOf(data)
b := &strings.Builder{}
for i := 0; i < v.NumField(); i++ {
if i > 0 {
b.WriteString(", ")
}
fmt.Fprint(b, v.Field(i).Interface())
}
return b.String()
}
Which of course gives the same result (and may or may not be faster, benchmark it). Try it on the Go Playground.
Can we use this approach, it will be applicable only to Person type struct though ?
https://play.golang.org/p/YI2Nu0q51ls
package main
import (
"fmt"
)
type Person struct {
FirstName string
LastName string
Age int
}
func (p Person) String() string {
return fmt.Sprintf("%s, %s, %d", p.FirstName, p.LastName, p.Age)
}
func main() {
p := Person{FirstName: "John",LastName: "Doe", Age: 25}
fmt.Printf("%v", p)
}
Output:
John, Doe, 25
Similar SO question:
ToString() function in Go

Golang - Unmarshal/rebuild an object in 2 step passing by interface

I'm working with json and golang. I've made a TCP server and, I need to Unmarshal the message to know which type of service is asked, before Unmarshal the contained data. It's a bit hard to explain so this is my code:
package main
import (
"fmt"
"encoding/json"
)
type Container struct {
Type string
Object interface{}
}
type Selling struct {
Surname string
Firstname string
//......
Price int
}
type Buying struct {
ID int
Surname string
Firstname string
//..........
}
/*
type Editing struct {
ID int
...............
}
Informations, etc etc
*/
func main() {
tmp_message_json1 := Selling{Surname: "X", Firstname: "Mister", Price: 10}
//tmp_message_json1 := Buying{ID: 1, Surname: "X", Firstname: "Mister"}
tmp_container_json1 := Container{Type: "Selling", Object: tmp_message_json1}
json_tmp, _ := json.Marshal(tmp_container_json1)
/*...........
We init tcp etc etc and then a message comes up !
...........*/
c := Container{}
json.Unmarshal(json_tmp, &c)
//I unmarshal a first time to know the type of service asked
// first question: Does Unmarshal need to be used only one time?
// does I need to pass c.Object as a string to unmarshal it in the called functions?
if c.Type == "Buying" {
takeInterfaceBuying(c.Object)
} else if c.Type == "client" {
takeInterfaceSelling(c.Object)
} else {
fmt.Println("bad entry")
}
}
func takeInterfaceBuying(Object interface{}) {
bu := Object
fmt.Println(bu.Firstname, bu.Surname, "wants to buy the following product:", bu.ID)
}
func takeInterfaceSelling(Object interface{}) {
se := Object
fmt.Println(se.Firstname, se.Surname, "wants to sell something for:", se.Price)
}
I need to handle messages which comes up like it, but I don't know if it's possible? does it possible?
Thank for help !
There is json.RawMessage for this purpose.
package main
import (
"encoding/json"
"fmt"
)
type Container struct {
Type string
Object json.RawMessage
}
type Selling struct {
Surname string
Firstname string
Price int
}
type Buying struct {
ID int
Surname string
Firstname string
}
func main() {
rawJson1 := []byte(`{"Type":"Selling","Object":{"Surname":"X","Firstname":"Mister","Price":10}}`)
rawJson2 := []byte(`{"Type":"Buying","Object":{"ID":1,"Surname":"X","Firstname":"Mister"}}`)
processMessage(rawJson1)
processMessage(rawJson2)
}
func processMessage(data []byte) {
var c Container
json.Unmarshal(data, &c)
switch {
case c.Type == "Buying":
processBuying(c)
case c.Type == "Selling":
processSelling(c)
default:
fmt.Println("bad entry")
}
}
func processBuying(c Container) {
var bu Buying
json.Unmarshal(c.Object, &bu)
fmt.Println(bu.Firstname, bu.Surname, "wants to buy the following product:", bu.ID)
}
func processSelling(c Container) {
var se Selling
json.Unmarshal(c.Object, &se)
fmt.Println(se.Firstname, se.Surname, "wants to sell something for:", se.Price)
}
I might be wrong, but I don't think you can do it in one step.
First idea: Unmarshal in map[string]interface{}
Don't use type with unmarshal, instead use a map[string]interface{}, and then construct Selling/Buying from this map (or use directly the map)
type Container struct {
Type string
Object map[string]interface{}
}
Second idea: Two steps / clueless container
First: Unmarshall in a clueless Container that doesn't know the type
type CluelessContainer struct {
Type string
Object interface{} `json:"-"` // or just remove this line ?
}
Then unmarshall in the type aware container. You could use a factory pattern to come with the right struct.

Can you pass a struct fieldname in to a function in golang?

Say for example you have something like this, trying to make the example as simple as possible.
type Home struct {
Bedroom string
Bathroom string
}
How do you pass the field name, or can you, to a function?
func (this *Home) AddRoomName(fieldname, value string) {
this.fieldname = value
}
Obviously that does not work... The only way I can see to do this is to use two functions which adds a lot of extra code when the struct gets really big and has a lot of similar code.
func (this *Home) AddBedroomName(value string) {
this.Bedroom = value
}
func (this *Home) AddBathroomName(value string) {
this.Bathroom = value
}
The only way that I am aware of is to use reflection:
func (this *Home) AddRoomName(fieldname, value string) {
h := reflect.ValueOf(this).Elem()
h.FieldByName(fieldname).Set(reflect.ValueOf(value))
return
}
http://play.golang.org/p/ZvtF_05CE_
One more idea that comes to my mind is like this, not sure if it makes sense in your case though:
func Set(field *string, value string) {
*field = value
}
home := &Home{"asd", "zxc"}
fmt.Println(home)
Set(&home.Bedroom, "bedroom")
Set(&home.Bathroom, "bathroom")
fmt.Println(home)
http://play.golang.org/p/VGb69OLX-X
Use type assertions on an interface value:
package main
import "fmt"
type Test struct {
S string
I int
}
func (t *Test) setField(name string, value interface{}) {
switch name {
case "S":
t.S = value.(string)
case "I":
t.I = value.(int)
}
}
func main() {
t := &Test{"Hello", 0}
fmt.Println(t.S, t.I)
t.setField("S", "Goodbye")
t.setField("I", 1)
fmt.Println(t.S, t.I)
}

Implementing dynamic strings in 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.
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}}
`
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
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"))
}

Resources