Hi All,
Recently I have been learning Embedded types and I encountered a problem.
This script runs without any runtime or compile problem, however
package main
import ("fmt")
type User struct {
Name string
}
type Person struct {
User
Model string
}
func (p Person) Talk() {
fmt.Println("Hi, my name is", p)
}
func main() {
p := Person{User{"John"}, "DM163"}
p.Talk()
}
It gives me Hi, my name is {{John} DM163},
So the question is : How to get rid of braces around “John” and “DM163” and why this is happening?
Hope it is not a troublesome question.
You are printing out p's struct information when you actually mean to print out p's individual fields.
For example:
package main
import (
"fmt"
)
type User struct {
Name string
}
type Person struct {
User
Model string
}
func (p Person) Talk() {
fmt.Println("Hi, my name is", p.Name)
// Or fmt.Println("Hi, my name is", p.User.Name)
}
func main() {
p := Person{User{"John"}, "DM163"}
p.Talk()
}
You could also implement the Stringer interface for the User type (See https://golang.org/pkg/fmt/#Stringer) which would then allow you to print out the User's information like you are doing. For example:
package main
import (
"fmt"
)
type User struct {
Name string
}
// Implement the Stringer interface for User.
func (u User) String() string {
return u.Name
}
type Person struct {
User
Model string
}
func (p Person) Talk() {
fmt.Println("Hi, my name is", p)
}
func main() {
p := Person{User{"John"}, "DM163"}
p.Talk()
}
When fmt.Println is passed some variable, it has to figure out how to convert the variable to a string. It has a default way of doing so, but a type should be able to override the default. So, fmt.Println will use the result of String() if the variable implements fmt.Stringer.
In other words, if your Person type has a String() string method (i.e., Person implements fmt.Stringer), then fmt.Println will use the result of calling Person.String() instead of its default.