This kind output required for debugging purpose.
To get actual value of slice of pointers, every time a iteration is getting required.
Is there any way, we can directly have the value instead of the address of each item present at slice using simple fmt.printf()?
Here is a code snippet :
https://play.golang.org/p/bQ5vWTlKZmV
package main
import (
"fmt"
)
type user struct {
userID int
name string
email string
}
func main() {
var users []*user
addUsers(users)
}
func addUsers(users []*user) {
users = append(users, &user{userID: 1, name: "cooluser1", email: "cool.user1@gmail.com"})
users = append(users, &user{userID: 2, name: "cooluser2", email: "cool.user2@gmail.com"})
printUsers(users)
printEachUser(users)
}
func printUsers(users []*user) {
fmt.Printf("users at slice %v \n", users)
}
func printEachUser(users []*user) {
for index, u := range users {
fmt.Printf("user at user[%d] is : %v \n", index, *u)
}
}
At above code, if I am printing the slice directly by fmt.printf , I get only the address of the values instead of actual value itself.
output : users at slice [0x442260 0x442280]
To read to the values always, i have to call func
like printEachUser
to iterate the slice and get the appropriate value .
output:
user at user[0] is : {1 cooluser1 cool.user1@gmail.com}
user at user[1] is : {2 cooluser2 cool.user2@gmail.com}
Is there any way, we can read the values inside the slice of pointers using fmt.printf
and get value directly like below ?
users at slice [&{1 cooluser1 cool.user1@gmail.com} , &{2 cooluser2 cool.user2@gmail.com}]
This kind output required for debugging purpose.
Is there any way, we can read the values inside the slice of pointers
using fmt.Printf
and get value directly like below ?
users []*user
fmt.Printf("users at slice %v \n", users)
users at slice [&{1 cooluser1 cool.user1@gmail.com}, &{2 cooluser2 cool.user2@gmail.com}]
Package fmt
import "fmt"
type Stringer
Stringer is implemented by any value that has a String method, which
defines the “native” format for that value. The String method is used
to print values passed as an operand to any format that accepts a
string or to an unformatted printer such as Print.
type Stringer interface {
String() string
}
For example,
package main
import (
"fmt"
)
type user struct {
userID int
name string
email string
}
type users []*user
func (users users) String() string {
s := "["
for i, user := range users {
if i > 0 {
s += ", "
}
s += fmt.Sprintf("%v", user)
}
return s + "]"
}
func addUsers(users users) {
users = append(users, &user{userID: 1, name: "cooluser1", email: "cool.user1@gmail.com"})
users = append(users, &user{userID: 2, name: "cooluser2", email: "cool.user2@gmail.com"})
fmt.Printf("users at slice %v \n", users)
}
func main() {
var users users
addUsers(users)
}
Playground: https://play.golang.org/p/vDmdiKQOpqD
Output:
users at slice [&{1 cooluser1 cool.user1@gmail.com}, &{2 cooluser2 cool.user2@gmail.com}]
Code : https://play.golang.org/p/rBzVZlovmEc
Output :
users at slice [{1 cooluser1 cool.user1@gmail.com} {2 cooluser2
cool.user2@gmail.com}]
Using stringers you can achive it.
Refer: https://golang.org/pkg/fmt/#Stringer
package main
import (
"fmt"
)
type user struct {
userID int
name string
email string
}
func (t user) String() string {
return fmt.Sprintf("{%v %v %v}", t.userID, t.name, t.email)
}
func main() {
var users []*user
addUsers(users)
}
func addUsers(users []*user) {
users = append(users, &user{userID: 1, name: "cooluser1", email: "cool.user1@gmail.com"})
users = append(users, &user{userID: 2, name: "cooluser2", email: "cool.user2@gmail.com"})
printUsers(users)
}
func printUsers(users []*user) {
fmt.Printf("users at slice %v \n", users)
}
You need not apply stringer to users i.e []*users instead if you do it just for a single user it'll work fine. Also it reduces down the string operations you need to do manually making your code elegant.
You can use spew
go get -u github.com/davecgh/go-spew/spew
func spewDump(users []*user) {
_, err := spew.Printf("%v", users)
if err != nil {
fmt.Println("error while spew print", err)
}
}
Output:
[<*>{1 cooluser1 cool.user1@gmail.com} <*>{2 cooluser2 cool.user2@gmail.com}]