Does Go support Inheritence? - go

I have heard a lot of people talk about Go, and how it does not support inheritance. Until actually using the language, I just went along with the crowd and listened to the hear say. After a little messing about with the language, getting to grips with the basics. I came across this scenario:
package main
type Thing struct {
Name string
Age int
}
type UglyPerson struct {
Person
WonkyTeeth bool
}
type Person struct {
Thing
}
type Cat struct {
Thing
}
func (this *Cat) SetAge(age int){
this.Thing.SetAge(age)
}
func (this *Cat GetAge(){
return this.Thing.GetAge() * 7
}
func (this *UglyPerson) GetWonkyTeeth() bool {
return this.WonkyTeeth
}
func (this *UglyPerson) SetWonkyTeeth(wonkyTeeth bool) {
this.WonkyTeeth = wonkyTeeth
}
func (this *Thing) GetAge() int {
return this.Age
}
func (this *Thing) GetName() string {
return this.Name
}
func (this *Thing) SetAge(age int) {
this.Age = age
}
func (this *Thing) SetName(name string) {
this.Name = name
}
now, what this does it composes the Person and Cat Structs, from the Thing Struct. By doing so, not only does the Person and Cat struct share the same Fields as the Thing Struct, but also, through composition, the methods of Thing are also shared. Is this not inheritance? Also by implenting an interface as such:
type thing interface {
GetName() string
SetName(name string)
SetAge(age int)
}
All three Structs are now joined or should I say, can be used in a homogenous fashion, such as an array of "thing".
So, I lay it on you, is this not inheritance?
Edit
Added a new derived Struct called "Ugly person" and Overridden the SetAge method for Cat.

It is inheritance but probably not the sort of inheritance you are probably after. Your example look promising b/c Person and Cat are behaviorally and structurally equal to each other modulo the type names.
As soon as you'd attempt to use this "inheritance" to 'extend' some base type with, for example added fields, you'll find that the receiver of the "base class" is always the base class, never the extended one. IOW, you cannot achieve structurally polymorphous type hierarchy.
OTOH, Go supports purely behavioral inheritance via interfaces. Embedding one interface into another does create an inheritance tree.
package main
import "fmt"
type Thing struct {
Name string
Age int
}
func (t *Thing) me() {
fmt.Printf("I am a %T.\n", t)
}
type Person struct {
Thing
}
func (p *Person) Iam() {
fmt.Printf("I am a %T.\n", p)
}
type Cat struct {
Thing
}
func (c *Cat) Iam() {
fmt.Printf("I am a %T.\n", c)
}
func main() {
var p Person
var c Cat
p.me()
p.Iam()
c.me()
c.Iam()
}

It's called composition. Methods of Person or Cat have no direct access to the fields of Thing. Also if e.g. Cat implements an own SetAge() and you want to call the one of Thing you would have to call myCat.Thing.SetAge(42) instead of myCat.SetAge(42).

Since you mentioned C#, try to do this in go. Method calls can't be made virtual in Go (except through interfaces).
// this is C#, not go
public class Thing
{
public virtual string Name {get; set;}
public virtual int Age {get; set;}
}
public class Person : Thing {}
public class Cat : Thing
{
public override int Age
{
get
{
return base.Age * 7; //age in cat's years
}
}
}
and call it like this:
Thing t = new Cat() {Name="Tom", Age=5}; // a Cat object is assigned
// to a Thing variable
Console.WriteLine(t.Age); // outputs 35.
// t.Age refers to Cat's implementation
// of Age, not Thing's. Notice how Age is virtual
// in Thing and overridden in Cat

Related

How to check if an attribute exists in an object's dynamic struct

I'm confused about how to check if an attribute exists in an object's dynamic struct. I.e. if we have the following structs:
type Animal struct {
Name string
Origin string
}
type Bird struct {
Animal
Speed float32
CanFly bool
}
type Bear struct {
Animal
Lazy bool
}
And now I have a function using Animal as a parameter:
func checkAminalSpeed (a Animal){
// if the struct of current animal doesn't have the Speed attribute
// print ("I don't have a speed")
//otherwise, return the speed of this animal
}
This function is trying to check the varible's runtime type to choose action.
I'd like to know in this case, how to write this checkAminalSpeed function? Thanks!
Go does not support inheritance, but perhaps you'll find the following approach tolerable.
Use an interface to define the Animal's behaviour:
type Animal interface {
GetName() string
GetOrigin() string
GetSpeed() float32
}
Use a "base" type that will contain common fields and also implement the behaviour:
type AnimalBase struct {
Name string
Origin string
}
func (a AnimalBase) GetName() string { return a.Name }
func (a AnimalBase) GetOrigin() string { return a.Origin }
func (a AnimalBase) GetSpeed() float32 { return -1 }
Embed the "base" type and override any behaviour you need to:
type Bird struct {
AnimalBase
Speed float32
CanFly bool
}
func (b Bird) GetSpeed() float32 { return b.Speed }
And then...
func checkAminalSpeed(a Animal) {
if speed := a.GetSpeed(); speed == -1 {
fmt.Println("I don't have speed")
} else {
fmt.Println(speed)
}
}
https://play.golang.org/p/KIjfC7Rdyls
mkopriva is right. Go does not support inheritance, you can use reflect and interface{} also
ps: reflect cost more time than interface
package main
import (
"fmt"
"reflect"
)
type Animal struct {
Name string
Origin string
}
type Bird struct {
Animal
Speed float32
CanFly bool
}
type Bear struct {
Animal
Lazy bool
}
func checkAminalSpeed (a interface{}){
v := reflect.ValueOf(a)
if f, ok := v.Type().FieldByName("Speed"); ok{
fmt.Printf("%v\n", f)
}
}
func main() {
checkAminalSpeed(Bird{})
checkAminalSpeed(Bear{})
}

How to deal with repetitiveness and flexibility when implementing Go interfaces?

I have a project that uses a structure like so:
type I interface {
GetName() string
DoSomething()
}
//
// A implements I
//
type A struct {
Name string
}
func (a *A) GetName() string {
return a.Name
}
func (a *A) DoSomething() {
...do something
}
//
// B implements I
//
type B struct {
Name string
}
func (b *B) GetName() string {
return b.Name
}
func (b *B) DoSomething() {
...do something
}
func (b *B) DoSomethingElse() {
...do something else
}
//
// Both
//
func UseAorB(T I) {
name := T.GetName()...
}
Is using GetName the best way to get the name field from either struct A or B when called in a function that takes interface I?
Do I have to redefine DoSomething every time for each thing that is meant to implement the interface? Or is there a better way to do this if DoSomething is the same every time where I can define it just once?
Struct B has a method that the interface does not define (DoSomethingElse). Do I need to use reflect to be able to pass Struct B to a function that takes interface I to call DoSomethingElse? Or should I be defining a new interface that includes this method?
I want to improve my code quality and write a solid library, but I have to say it feels like I am fighting the language and making my life more difficult.
Yes, GetName() is a good way of doing that
If you have similar implementations of a method, you can usually move it to a common struct and embed that:
type Common struct {}
func (c Common) DoSomething() {...}
type A struct {
Common
Stuff
}
type B struct {
Common
Other stuff
}
Above, both A and B have DoSomething method, and they share the implementation
Do not use reflect. There are two ways:
Use type assertion:
func f(in I) {
if b, ok:=in.(B); ok {
// b is of type B, so:
b.DoSomethingElse()
}
}
Use an interface and type assertion:
type DoesSometingElse interface {
DoSomethingElse()
}
func f(in I) {
if x, ok:=in.(DoesSomethingElse); ok{
x.DoSomethingElse()
}
}
If you feel like you're fighting with the language, then either you are modeling something incorrectly, or you don't know the right way to do something in that language. There are good and bad ways of doing things in all languages, and many times these are different for each language. If you are coming to Go from another language, you should first stop trying to think in that other language and translate to Go, and try to work with Go alone.

How to pass mutiple type array in single func

I have multiple structs
type Base struct {
Id string
Name string
Code string
}
type Country struct {
Base
...
}
type City struct {
Base
...
}
And I need to make a function that takes an array of City or Country. Currently, I have one func for each type which is doing the same thing and I guess that isn't the best/good way to do it!
Thanks
It looks like you're trying to recreate class inheritance in Go. Go does not have class inheritance on purpose. Do not try to recreate it. I believe you're thinking "Country is a Base." That's not correct. Country embeds a Base. That's not the same thing. This matters for how you name things. In this case, it seems that "Base" is really "location metadata", so we'll call it that.
type LocationMeta struct {
id string
name string
code string
}
And you want an interface to work with for all kinds of locations.
type Location interface {
Id() string
Name() string
Code() string
}
We can conform LocationMeta to Location, though this is possibly a little strange (is the metadata really a Location?). But it works.
func (b LocationMeta) Id() string {
return b.id
}
func (b LocationMeta) Name() string {
return b.name
}
func (b LocationMeta) Code() string {
return b.code
}
And we can embed LocationMeta in a City:
type City struct {
LocationMeta
}
And for free, City now conforms to Location.
That said, usually you don't bother with this kind of embedding for such a small thing with no logic of its own. That's really overkill; I was just demonstrating it because you seem to be using it. Normally, you'd just conform each type itself:
type Country struct {
id string
name string
code string
}
func (c Country) Id() string {
return c.id
}
func (c Country) Name() string {
return c.name
}
func (c Country) Code() string {
return c.code
}
The great thing about Go is that it doesn't care how you conform to the interface. City and Country both conform to Location, in completely different ways, and that's totally fine.
So you can then create a city:
boston := City{LocationMeta{id: "bos", name: "Boston", code: "bos"}}
See how weird this is? We have to create a LocationMeta because of the embedded object. It can be worth it sometimes (and is incredibly powerful), but I would probably have done both City and Country the Country way (with no LocationMeta):
us := Country{id: "us", name: "USA", code: "us"}
But still, they're both Locations, so we can put them in a slice:
locations := []Location{boston, us}
And pass them to things:
func printLocations(locations []Location) {
fmt.Println(locations)
}
printLocations(locations)
Playground of this code
Playground using embedding for everything
Playground of more typical approach with just structs
i already posted this in the comments but you can do this
func myfunc(in interface{}) {
switch in.(type) {
case []Country:
// country logic here
case []City:
// city logic here
}
}

Wrapping multiple implementations in Go

I have an application that has multiple concurrent implementations of the same API (e.g. one backed by a SQL database and another by a dataset stored in an XML file). What I'd really like to do is to define a parent type for each type of thing in the API that
holds the member variables that are common to all of the implementations and
defines the methods that all implementations must have.
So, in (invalid) Go, I want to do something like:
type Person interface {
Name string
Title string
Position string
Boss() *Person
}
type Person_XML struct {
Person
}
func (p *Person_XML) Boss() (*Person, error) {
// Poke around an XML document and answer the question
return boss, nil
}
type Person_SQL {
Person
}
func (p *Person_SQL) Boss() (*Person, error) {
// Do a DB query and construct the record for the boss
return boss, nil
}
But, of course, that's not legal since only structs have member variables and only interfaces have member functions. I could do this with just interfaces like this:
type Person interface {
Name() string
Title() string
Position() string
Boss() Person
}
type Person_XML struct {
NameValue string
TitleValue string
PositionValue string
Person
}
func (p *Person_XML) Name() string {
return p.NameValue
}
func (p *Person_XML) Title() string {
return p.TitleValue
}
func (p *Person_XML) Position() string {
return p.PositionValue
}
func (p *Person_XML) Boss() (Person, error) {
// Poke around an XML document and answer the question
return boss, nil
}
and similarly for other implementations. Is there an alternative that doesn't force me to turn member variables into member functions? What's best practice for such a use case?
Best practice would be to provide an interface:
type Person interface {
PersonName() string
PersonTitle() string
PersonPosition() string
Boss() (Person, error)
}
And also provide a struct which contains the common fields and the methods to get them:
type BasePerson struct {
Name string
Title string
Position string
}
func (p *BasePerson) PersonName() string { return p.Name }
func (p *BasePerson) PersonTitle() string { return p.Title }
func (p *BasePerson) PersonPosition() string { return p.Position }
(Note: *BasePerson itself does not implement Person as it doesn't have a Boss() method.)
Any type that embeds *BasePerson will automatically have its methods promoted, and so to implement Person, only the Boss() method will need to be added.
For example:
type PersonXML struct {
*BasePerson
}
func (p *PersonXML) Boss() (Person, error) {
// Poke around an XML document and answer the question
var boss *PersonXML
return boss, nil
}
*PersonXML does implement Person.
Example using it:
var p Person
p = &PersonXML{
BasePerson: &BasePerson{
Name: "Bob",
Title: "sysadmin",
Position: "leader",
},
}
fmt.Println(p.PersonName())
Output (try it on the Go Playground):
Bob
To create the PersonSQL type, you again only have to add the Boss() method if you embed *BasePerson:
type PersonSQL struct {
*BasePerson
}
func (p *PersonSQL) Boss() (Person, error) {
// Do a DB query and construct the record for the boss
var boss *PersonSQL
return boss, nil
}
*PersonSQL again does implement Person.
We can apply first approach since struct can embed interface along with fields. If you look at package sort It uses same approach in which it embeds an interface inside an struct.
type Interface interface {
// Len is the number of elements in the collection.
Len() int
// Less reports whether the element with
// index i should sort before the element with index j.
Less(i, j int) bool
// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}
type reverse struct {
// This embedded Interface permits Reverse to use the methods of
// another Interface implementation.
Interface
}
So doing your approach is absolutely valid. And you can implement interface easily using struct receiver.
// Less returns the opposite of the embedded implementation's Less method.
func (r reverse) Less(i, j int) bool {
return r.Interface.Less(j, i)
}

How can two different types implement the same method in golang using interfaces?

Say I have two structs:
type First struct {
str string
}
type Second struct {
str string
}
And I want both of them to implement interface A:
type A interface {
PrintStr() //print First.str or Second.str
}
It seems redundant to have an implementation for both First and Second structs like so:
func (f First) PrintStr() {
fmt.Print(f.str)
}
func (s Second) PrintStr() {
fmt.Print(s.str)
}
Is there a way I can have one implementation for all the structs implementing interface A? Something like this, but it doesn't seem to work:
func (a A) PrintStr() {
fmt.Print(a.str)
}
Thank you!
No you can't, but you could create a base type and then embed it into your 2 struct, therefore only needing an implementation for the base type:
type WithString struct {
str string
}
type First struct {
WithString
}
type Second struct {
WithString
}
type A interface {
PrintStr() //print First.str or Second.str
}
func (w WithString) PrintStr() {
fmt.Print(w.str)
}
Usage:
a := First{
WithString: WithString{
str: "foo",
},
}
Complete Example on Playground
Embed documentation
If the printing logic depends on the interface but not on the structs themselves, then it is better to move printing to a free function that operates over an interface.
In your case, the PrintStr method is used to print a string which is a member of each structure.
In this case, it means that each structure should implement an interface that returns the necessary string used for printing, and PrintStr becomes a function taking a Printable parameter.
type First struct {
str string
}
type Second struct {
str string
}
type Printable interface {
String() string
}
func (p First) String() string {
return p.str
}
func (p Second) String() string {
return p.str
}
func PrintStr(p Printable) {
fmt.Print(p.String())
}
Your use of the A interface is non-idiomatic because an interface should not depend on the implementation of its functionality.
Instead, with this solution, you can still keep the A interface, but simplify each implementation:
func (f First) PrintStr() {
PrintStr(f)
}
func (s Second) PrintStr() {
PrintStr(s)
}
It is still redundant, but the logic lies in the function that is called from there, limiting the need to do copy-pasting in case of modification of the printing logic.
This pattern is common in the Go standard library, because many useful functions are built upon interfaces which they cannot extend, for example io.Reader.
It is a simple interface with only one method, but it is used thoroughly from many other packages.
If you look at the ioutil.ReadAll function, it could be argued that it could have been implemented as another method of the io.Reader interface, however this keeps readers simpler, concentrating on their single method, while allowing any implementor to use ReadAll for free.
Maybe not the best way to solve your problem, but you could use a wrapper in order to avoid "implementing" the function twice, something like this:
type First struct {
str StringWrapper
}
type Second struct {
str StringWrapper
}
type StringWrapper struct {
str string
}
func (f StringWrapper) PrintStr() {
fmt.Print(f.str)
}
func main() {
var a First = First{str:StringWrapper{str: "aaa"}};
a.str.PrintStr();
}
Why don't you just leave that function out of the interface and pass type A as a parameter?
type A interface {}
type First struct {
str string
}
type Second struct {
str string
}
func PrintStr(a A) {
fmt.Print(a.str)
}

Resources