I'm trying to use inheritance in Go, and although inheritance isn't 'technically' supported (as far as I know), you can get similar functionality by using anonymous fields.
Here's how I'm defining 'inheritance' for across two structs:
//Parent struct:
type FSEntity struct {
guid GUIDNumber
}
//Child struct:
type DataBlock struct {
FSEntity
data []byte
}
I now have a function defined as following, which is supposed to accept an instance of the parent struct FSEntity
:
Put(entity FSEntity) {....}
But when I try passing an instance of DataBlock
(which through inheritance is also FSEntity
) into the Put
function above like so:
guidNumber := GUIDNumber(1234)
value := []byte("sample string")
dataBLock := DataBlock{FSEntity{guidNumber}, value}
Put(dataBLock)
On the last line above, I get this error:
cannot use dataBLock (type DataBlock) as type FSEntity in argument to Put
How do I resolve this ?
I think the terminology you're using is causing you problems. In the put, you simply need to reference the inner struct like so; Put(dataBLock.FSEntity)
But to clarify, there is no parent/child relationship here. You're using a language feature called embedding and works like composition (ie one type is composed of others) only the things you embed have their fields/methods hoisted to the embedding scope. For that reason you can't pass in the type you're calling the 'child' because there is no polymorphic behavior here like when you inherit from a type, instead you're type is composed of that but you can access it's fields without the extra level of indirection. Since your method accepts the embedded type as an argument, you have to explicitly reference it to pass only that. The outer struct is in no way that type.
The easiest way to solve it is to satisfy the parameter's type: pass a FSEntity
. If you need to only get FSEntity
from a struct which is embedding it, then you can simply do dataBlock.FSEntity
.
//Parent struct:
type FSEntity struct {
guid string
}
//Child struct:
type DataBlock struct {
FSEntity
data []byte
}
func main() {
myVar := DataBlock{}
myVar.guid = "test"
myVar.data = []byte("moar test")
a(myVar.FSEntity)
}
func a(x FSEntity) {
fmt.Printf("%+v
", x)
}
It's not exactly inheritance and the idea is to define Put as method
func (entity FSEntity) Put() {....}
then after embedding
type DataBlock struct {
FSEntity
data []byte
}
DataBlock can use this method
dataBLock.Put()
package main
import (
"fmt"
)
type Guider interface {
Guid() string
}
type FSEntity struct {
guid string
}
func (e FSEntity) Guid() string {
return e.guid
}
//Child struct:
type DataBlock struct {
FSEntity
data []byte
}
func main() {
myVar := DataBlock{}
myVar.guid = "test"
myVar.data = []byte("moar test")
Put(myVar)
}
func Put(x Guider) {
fmt.Printf("%+v
", x)
}
An interface will help you to accept the parent struct