Golang: Type assign with another struct

embedding, go, methods, struct

Solution

This:

type Form Rectangle

Creates a new type named `Form`, having `Rectangle` as its underlying type.

This means that the fields of `Rectangle` (which is a struct) will be defined for `Form` as well.

But methods are bound to a specific type. When you create a new type (`Form`), that new type will not have any of the methods of its underlying type, so you can't call `c.SomethingElse()` as `SomethingElse()` is a method of the `Rectangle` type.

`c.Circle.Something()` works, because `c.Circle` is a field of type `Circle`, and `Something()` is a method of the `Circle` type.

If you want to call the `Rectangle.SomethingElse()` method, that requires a value of type `Rectangle` (the receiver type is `Rectangle`). Since underlying type of `Form` is `Rectangle`, you can simply obtain a value of type `Rectangle` from a value of type `Form` using a simple type conversion:

Rectangle(c).SomethingElse() // This works

The benefit of creating a new type is that so you can create / add your own methods for it. A common example is implementing the `sort.Interface` interface. Let's say you have a slice of something, e.g. `[]Rectangle`, or a slice of some type which you have no control over (beause it's part of another package – and methods for a type can only be defined in the same package). If you want to sort this slice, you create a new type for which you can define methods, the methods of `sort.Interface`, e.g.:

type SortRectangle []Rectangle

func (s SortRectangle) Len() int           { return len(s) }
func (s SortRectangle) Less(i, j int) bool { return s[i] <some-logic> s[j] }
func (s SortRectangle) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

The `sort.Sort()` function is able to sort any values that implement `sort.Interface`. The `[]Rectangle` does not, but we just created a new type `SortRectangle` which does. And if we have a value of type `[]Rectangle`, we can convert it to `SortRectangle` because the former is the underlying type of the latter, and by doing a conversion, we have a value of type `SortRectangle` which can be passed to `sort.Sort()`, in order to have it sorted:

rs := []Rectangle{}
// Sort rs:
sort.Sort(SortRectangle(rs))

Note that a conversion like the above `SortRectangle(rs)` only changes the runtime type information, it does not change the memory representation of `rs`, so it's pefectly safe and efficient.

If you want the new type to have the methods of the "old" type, then use embedding. See Ainar-G's answer. In fact, you already did this by embedding `Circle` in `Rectangle`: the type `Rectangle` has a method `Something()`, because `Something()` is a method of `Circle`:

Rectangle{}.Something()  // Prints "something"

Problem

So I have this example here: Go Playground ``` package main import ( "fmt" ) type Circle struct{} func (c Circle) Something() { fmt.Println("something") } type Rectangle struct { Circle } func (a Rectangle) SomethingElse() { fmt.Println("SomethingElse") } type Form Rectangle func main() { c := Form{} c.Circle.Something() c.SomethingElse() } ``` I don't understand why I can call `Something` from the embedded `Circle`, but cannot call `Somethingelse` from the `Rectangle` within the `Form` type. Also I don't understand what benefit I get when I declare a type of some other type, like here in `Form`.

Original source