4

Is there beside copying the inner Box value by hand a language feature to down-cast RatedBox into a Box?

type Box struct {
    Name string
}

type RatedBox struct {
    Box
    Points int
}

func main() {
    rated := RatedBox{Box: Box{Name: "foo"}, Points: 10}

    box := Box(rated) // does not work
}

go-playground

// works, but is quite verbose for structs with more members
box := Box{Name: rated.Name}
icza
  • 389,944
  • 63
  • 907
  • 827
Paradiesstaub
  • 2,590
  • 2
  • 18
  • 28

1 Answers1

9

Embedding a type in a struct adds a field to the struct, and you can use the unqualified type name to refer to it (unqualified means omit the package name and the optional pointer sign).

For example:

box := rated.Box
fmt.Printf("%T %+v", box, box)

Output (try it on the Go Playground):

main.Box {Name:foo}

Note that assignment copies the value, so the box local variable will hold a copy of the value of the RatedBox.Box field. If you want them to be the "same" (to point to the same Box value), use a pointer, e.g.:

box := &rated.Box
fmt.Printf("%T %+v", box, box)

But here of course type of box will be *Box.

Or you may choose to embed the pointer type:

type RatedBox struct {
    *Box
    Points int
}

And then (try it on the Go Playground):

rated := RatedBox{Box: &Box{Name: "foo"}, Points: 10}

box := rated.Box
fmt.Printf("%T %+v", box, box)

Output of the last 2:

*main.Box &{Name:foo}
icza
  • 389,944
  • 63
  • 907
  • 827
  • 3
    Go isn't object oriented in the same way C++ or Java is. For cases where you need polymorphism you should use interfaces. This answer is the best you can do without them. – Milo Christiansen Jul 26 '17 at 13:20