33

Check out this sandbox

When declaring a struct that inherits from a different struct:

type Base struct {
    a string
    b string
}

type Something struct {
    Base
    c string
}

Then calling functions specifying values for the inherited values gives a compilation error:

f(Something{
    a: "letter a",
    c: "letter c",
})

The error message is: unknown Something field 'a' in struct literal.

This seems highly weird to me. Is this really the intended functionality?

Thanks for the help!

4 Answers 4

43

Golang doesn't provide the typical notion of inheritance. What you are accomplishing here is embedding.

It does not give the outer struct the fields of the inner struct but instead allows the outer struct to access the fields of the inner struct.

In order to create the outer struct Something you need to give its fields which include the inner struct Base

In your case:

Something{Base: Base{a: "letter a"}, c: "letter c"}
Sign up to request clarification or add additional context in comments.

2 Comments

one good consequence is that if you do json.Marshal you will get the {a, b, c} structure you want
What're the differences from type Something struct { Base Base c string }?
11

You need to explicitly create Base field like that

f(Something{
    Base: Base{a: "letter a"},
    c:    "letter c",
})

Go has no inheritance, it is just composition.

2 Comments

Composition is the ubiquitous computer science term, worth pointing out though that the actual Go feature being utilized here is embedding.
@evanmcdonnal True, but I intentionally used this wording, because of en.wikipedia.org/wiki/Composition_over_inheritance
5

You have to actually instantiate the embedded struct as well. Just so you know this isn't inheritance technically, no such feature exists in Go. It's called embedding. It just hoists fields and methods from the embedded type to the embeddors scope. So anyway, the composite literal instantiation you're trying to do would look like this;

f(Something{
    Base: Base{a: "a", b: "b"},
    c:    "c",
})

Comments

3

Read the example from Go by Example: Struct Embedding, the trick part is that we need to explicitly initialize the embedded struct, but we can directly access the embedded fields.

type base struct {
    num int
}
type container struct {
    base
    str string
}
// initialize the embedding explicitly
co := container{
    base: base{
       num: 1,
    },
    str: "some name",
}
// however, the embedded field can be accessed directly
fmt.Printf("co={num: %v, str: %v}\n", co.num, co.str)
// this also works
fmt.Println("also num:", co.base.num)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.