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`.