A beginner question: About Embedded types

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. :confounded:

Hey @Redmond_D,

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()
}
1 Like

It took quite a bit of time to understand stringer.

To be honest, i am still a bit of confused. It looks like the stringer interface can choose specific struct type to override the fmt.Println in main

Its the other way around.

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.

2 Likes

Understand!

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.