I have done the following:
availableObjs[]interface{}
GoPlayground Code : https://play.golang.org/p/jdHpueokrEk
Tried searching online.
Same Code inline :
package main
import (
"fmt"
"reflect"
)
////// Parent Interface which has Display() fn.
type Parent interface {
Display()
}
// 2 Child structs implementing their Display() fn.
type Child1 struct {
name1 string
}
type Child2 struct {
name2 string
}
func (c1 Child1) Display() {
fmt.Println("c1Name : ", c1.name1)
}
func (c2 Child2) Display() {
fmt.Println("c2Name : ", c2.name2)
}
////////////////////////////////////////////
// Maintains the created objects
var availableObjs []interface{}
func main() {
//// Creating 2 objects
c1 := Child1{"Child1"}
c2 := Child2{"Child2"}
// Adding 2 objects to availableObjs
availableObjs = append(availableObjs, c1)
availableObjs = append(availableObjs, c2)
// Now, want to fetch the Object from Interface and call its respective Display() fn.
for _, obj := range availableObjs {
fmt.Println("")
fmt.Println("Obj Got = ",obj)
fmt.Println("Obj type = ",reflect.TypeOf(obj))
//obj.Display() // <-- Problem Line
}
}
Need to do : Need inputs on how I can call Display() function after getting object from array interface.
There are two ways you can do this: one is by instead of using the empty interface you use the proper Parent interface to declare the slice:
// Maintains the created objects
var availableObjs []Parent
Please note that the naming of Parent
for your interface suggests that you are approaching interfaces with the concept of inheritance, which is not something we use in Go. You must think of interfaces more like a behaviour. In this particular case, you want to represent the behaviour of something capable of "displaying", so you may well call the interface Displayer
.
This naming convention, appending -er
to the interface name, is a very common pattern in Go, even though sometimes you get some strange names :)
In the same sense, the Child
structs are not actually children of the Parent interface, they are just structs that implicitly satisfy the interface.
They could satisfy any number of interfaces at the same time. For instance, if they had a String() method they would also satisfy the fmt.Stringer
interface.
Now, the second option is to use a type assertion, either with a switch statement or a type statement:
switch t := obj.(type) {
case Parent:
t.Display() // note that 't' is the new typed variable
}
Or
t, ok := obj.(Parent)
if ok {
t.Display()
}
Please note that the ok
variable above can be omitted, but in that case the code will panic if the type assertion doesn't match.