In Go, if type T2 is based on type T1, is there any “inheritance” from T1 to T2?

If type T2 based on type T1 other than sharing the same data fields, is there any connection between T1 and T2 ?

  package main
 import "fmt"

 type T1 struct {s string}
 func (v * T1) F1 () string {return vs}

 type T2 T1
 func (v * T2) F2 () string {return vs}

 func main () {
         var t1 = T1 {"xyz"}
         var t2 = T2 {"pdq"}
         s0: = t2.F1 () // error - expected ok
         s1: = ((* T1) (& t2)). F1 () // ok - expected
         s2: = ((* T2) (& t1)). F2 () // ok - not expected
         fmt.Println (s0, s1, s2)
 }

My understanding is missing here

  • hoped that T2 inherits the methods of T1 , but this is not so.

  • expected that T2 could be forced into T1 , since it was obtained from T1

  • I was surprised that T1 can be forcibly entered into T2 , but the way it is.

  • it seems that the connection between T1 and T2 completely symmetrical - I can’t find anything that breaks the symmetry, despite the fact that it is actually obtained from another - or is it an illusion?

(NOTE: I do not criticize or judge - I fully respect the decisions made - I just check that I understand that there is something that contradicts intuition for me - I'm sure I'm not the only one!)

+4
source share
4 answers

Go does not support object-oriented type inheritance.

Is an object an object oriented language?

Why is there no type inheritance?

The method is bound to one specific type.

A method declaration binds a method identifier. This method is said to be associated with a base type and only displayed in selectors for that type.

You can convert between types T1 and T2 .

The value of x can be converted to input T [when] x type and T have identical base types.

For instance,

 package main import ( "fmt" ) type T1 struct{ i int } func (t T1) String() string { return "T1" } type T2 T1 func (t T2) String() string { return "T2" } func main() { t1 := T1{1} t2 := T2{2} fmt.Println(t1, t2) c1 := T1(t2) c2 := T2(t1) fmt.Println(c1, c2) t1 = T1(c2) t2 = T2(c1) fmt.Println(t1, t2) } Output: T1 T2 T1 T2 T1 T2 
+4
source
 s2 := ((*T2)(&t1)).F2() // ok - not expected 

works because you throw it on type T2 and that allows F2 . Therefore, it is expected that it will work. Then the function F2 is called on your T2 object t1 , which returns t1.s

 s0 := t2.F1() // error - expected ok 

For this, I can’t tell you exactly, but only give you my believable idea:

F1 is a method of type T1. Since t2 is not of type T1, you cannot call F1 on t2. So, as you noted, only data fields are separated, not methods of these types.

Also see Go For C ++ Programmers , which says:

Methods are defined for the named types. If you convert the value to another type, the new value will have methods of the new type, not the old one.

0
source

I can explain why T2 does not have T1 methods. Imagine you need to sort some data of type T two different ways. One way is by default, so you use the Len , Less and Swap methods in T You can call sort.Sort(data) and sort the default data. But how to sort the data in different ways?

You write type SortDifferently T and implement the Len , Less and Swap methods for the type SortDifferently . If SortDifferently had all the T methods, you could not do this because Go does not have method overrides. But without inheritance, you can now write sort.Sort((SortDifferently)data) to sort the data in different ways.

This is a way to do something. It’s not easy to get used to.

0
source

Not sure if this will help you, but look at the “anonymous fields” described, for example, in “Go for C ++ programmers,” under the “Interfaces” section - they seem to provide something similar to child classes.

But anyway, after reading the Go tutorials, I came up with the idea that Go authors strongly wanted programmers to avoid creating inheritance chains and instead use nesting / delegation.

0
source

All Articles