Go Structs Embedded Fields: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
(Created page with "=Internal= =Overview= =TO DEPLETE= <font color=darkkhaki> Field embedding is used to share state in inheritance. When only the type but not the name of a filed is declared, the name of the field is implicitly the unqualified name of the type, and the field is called an '''embedded field''' or an anonymous field: <syntaxhighlight lang='go'> type SomeInterface interface { ... } type SomeOtherStruct struct { s...")
 
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
=External=
* https://go.dev/ref/spec#Struct_types
=Internal=
=Internal=


=Overview=
=Overview=
=Embedding, Interfaces and Polymorphism=


=TO DEPLETE=
=TO DEPLETE=
Line 30: Line 35:
</font>
</font>
Note that if an embedded field is specified using the package and the type name (the qualified type name), the implicit field name is the unqualified type name.
Note that if an embedded field is specified using the package and the type name (the qualified type name), the implicit field name is the unqualified type name.
====<span id='Embedded_Fields_and_Methods'></span>Embedded Field Promotion====
==<span id='Embedded_Fields_and_Methods'></span>Embedded Field Promotion==
The embedded field's type identifiers are promoted to the embedding type, so they can be accessed as it would belong to the embedding type. Promotion also applies to methods associated with the embedded type. A method associated with the embedded type works with the embedding type. This strengthens the point that embedded fields model an "is-a" relationship, and elevates the field embedding mechanism to a sort of inheritance mechanism. Type embedding is the Go's "extends". It allows types to extend, and it changes their behavior.  
The embedded field's type identifiers are promoted to the embedding type, so they can be accessed as it would belong to the embedding type. Promotion also applies to methods associated with the embedded type. A method associated with the embedded type works with the embedding type. This strengthens the point that embedded fields model an "is-a" relationship, and elevates the field embedding mechanism to a sort of inheritance mechanism. Type embedding is the Go's "extends". It allows types to extend, and it changes their behavior.  


Line 67: Line 72:
Also see: {{Internal|Go_Language_Object_Oriented_Programming#Structs_as_Receiver_Types|structs as Receiver Types}}
Also see: {{Internal|Go_Language_Object_Oriented_Programming#Structs_as_Receiver_Types|structs as Receiver Types}}


=====Promoted Fields=====
===Promoted Fields===
<font color=darkkhaki>TODO: https://go.dev/ref/spec#Struct_types</font>
<font color=darkkhaki>TODO: https://go.dev/ref/spec#Struct_types</font>


====Embedded Field Identity====
==Embedded Field Identity==
The embedded field always exists in and of itself. It never loses its identity and it can be always accessed directly:
The embedded field always exists in and of itself. It never loses its identity and it can be always accessed directly:
<syntaxhighlight lang='go'>
<syntaxhighlight lang='go'>
dog.Animal.name
dog.Animal.name
</syntaxhighlight>
</syntaxhighlight>
====Overriding Embedded Fields====
==Overriding Embedded Fields==
The embedding type can override the embedding field elements, and reuse the identifiers, associate them with other types, etc. Both fields and methods can be overridden. This behavior provides [[Go_Language_Object_Oriented_Programming#Polymorphism|polymorphism]].
The embedding type can override the embedding field elements, and reuse the identifiers, associate them with other types, etc. Both fields and methods can be overridden. This behavior provides [[Go_Language_Object_Oriented_Programming#Polymorphism|polymorphism]].
<syntaxhighlight lang='go'>
<syntaxhighlight lang='go'>
Line 99: Line 104:
</syntaxhighlight>
</syntaxhighlight>
When the embedding type does not want to implement an embedded type interface, it can override at least one of the method of the embedded type method set. <font color=darkkhaki>Example required.</font>
When the embedding type does not want to implement an embedded type interface, it can override at least one of the method of the embedded type method set. <font color=darkkhaki>Example required.</font>
==Retire "Go_Inheritance_and_Polymorphism"==
Retire: {{Internal|Go_Inheritance_and_Polymorphism#Overview|Go_Inheritance_and_Polymorphism}}

Latest revision as of 02:15, 4 November 2024

External

Internal

Overview

Embedding, Interfaces and Polymorphism

TO DEPLETE

Field embedding is used to share state in inheritance. When only the type but not the name of a filed is declared, the name of the field is implicitly the unqualified name of the type, and the field is called an embedded field or an anonymous field:

type SomeInterface interface {
   ...
}

type SomeOtherStruct struct {
   s string
}

type Item struct {
	SomeInterface
    SomeOtherStruct
	int
}

Embedded fields, unlike named fields, model an is-a relationship.

An embedded field can be a type name T, a pointer to a non-interface type name (*T), and T itself may not be a pointer type. As mentioned above, the unqualified type name becomes the implicit field name. The previous example declares three embedded fields, one of type int, one of type SomeInterface, which is an interface declared somewhere in the package and the third of type SomeOtherStruct, which is a struct type declared somewhere else in the package. The type renders as:

{SomeInterface:<nil> SomeOtherStruct:{s:} int:0}

Note that if an embedded field is specified using the package and the type name (the qualified type name), the implicit field name is the unqualified type name.

Embedded Field Promotion

The embedded field's type identifiers are promoted to the embedding type, so they can be accessed as it would belong to the embedding type. Promotion also applies to methods associated with the embedded type. A method associated with the embedded type works with the embedding type. This strengthens the point that embedded fields model an "is-a" relationship, and elevates the field embedding mechanism to a sort of inheritance mechanism. Type embedding is the Go's "extends". It allows types to extend, and it changes their behavior.

Field promotion:

type Animal struct {
	name string
}

type Dog struct {
	Animal
}

dog := &Dog{Animal{"Fido"}}

...

fmt.Printf("name: %s\n", dog.name) // the "name" field is promoted into the Dog structure

Method promotion, for the same structs Animal and Dog declared above:

func (a *Animal) Move() {
	fmt.Printf("%s moves\n", a.name)
}

...

dog.Move() // Displays "Fido moves"

In the example above, the invocations dog.Move() and dog.Animal.Move() are equivalent.

If an interface is implemented by the embedded type, it is promoted to the embedding type.

Also see:

structs as Receiver Types

TODO: https://go.dev/ref/spec#Struct_types

Embedded Field Identity

The embedded field always exists in and of itself. It never loses its identity and it can be always accessed directly:

dog.Animal.name

Overriding Embedded Fields

The embedding type can override the embedding field elements, and reuse the identifiers, associate them with other types, etc. Both fields and methods can be overridden. This behavior provides polymorphism.

type Animal struct {
	name string
}

func (a *Animal) Move() {
	fmt.Printf("%s moves\n", a.name)
}

type Dog struct {
	Animal
}

func (d *Dog) Move() {
	fmt.Printf("%s jumps\n", d.name)
}

...
dog := &Dog{Animal{"Fido"}}
dog.Move() // will print "Fido jumps"

When the embedding type does not want to implement an embedded type interface, it can override at least one of the method of the embedded type method set. Example required.

Retire "Go_Inheritance_and_Polymorphism"

Retire:

Go_Inheritance_and_Polymorphism