| 24 | } |
| 25 | |
| 26 | func main() { |
| 27 | |
| 28 | // When creating structs with literals, we have to |
| 29 | // initialize the embedding explicitly; here the |
| 30 | // embedded type serves as the field name. |
| 31 | co := container{ |
| 32 | base: base{ |
| 33 | num: 1, |
| 34 | }, |
| 35 | str: "some name", |
| 36 | } |
| 37 | |
| 38 | // We can access the base's fields directly on `co`, |
| 39 | // e.g. `co.num`. |
| 40 | fmt.Printf("co={num: %v, str: %v}\n", co.num, co.str) |
| 41 | |
| 42 | // Alternatively, we can spell out the full path using |
| 43 | // the embedded type name. |
| 44 | fmt.Println("also num:", co.base.num) |
| 45 | |
| 46 | // Since `container` embeds `base`, the methods of |
| 47 | // `base` also become methods of a `container`. Here |
| 48 | // we invoke a method that was embedded from `base` |
| 49 | // directly on `co`. |
| 50 | fmt.Println("describe:", co.describe()) |
| 51 | |
| 52 | type describer interface { |
| 53 | describe() string |
| 54 | } |
| 55 | |
| 56 | // Embedding structs with methods may be used to bestow |
| 57 | // interface implementations onto other structs. Here |
| 58 | // we see that a `container` now implements the |
| 59 | // `describer` interface because it embeds `base`. |
| 60 | var d describer = co |
| 61 | fmt.Println("describer:", d.describe()) |
| 62 | } |