Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Impossible type assertions with casting from interface type to the actual type

Tags:

go

I'm getting two errors,

a. Impossible Type assertion. Can we cast from interface type to the actual type object

b. not sure what's the meaning of evaluated but not used

type IAnimal interface {
    Speak()
}
type Cat struct{}

func (c *Cat) Speak() {
    fmt.Println("meow")
}



type IZoo interface {
    GetAnimal() IAnimal
}
type Zoo struct {
    animals []IAnimal
}
func (z *Zoo) GetAnimal() IAnimal {
    return z.animals[0]
}

Testing

var zoo Zoo = Zoo{}

// add a cat
var cat IAnimal = &Cat{}
append(zoo.animals, cat) // error 1: append(zoo.animals, cat) evaluated but not used

// get the cat

var same_cat Cat = zoo.GetAnimal().(Cat) // error 2: impossible type assertions

fmt.Println(same_cat)

go Playground

like image 247
user2727195 Avatar asked Mar 13 '17 21:03

user2727195


1 Answers

  1. The error message pretty much says it all:

    tmp/sandbox129360726/main.go:42: impossible type assertion:
        Cat does not implement IAnimal (Speak method has pointer receiver)
    

    Cat does not implement IAnimal, because Speak (part of the IAnimal interface) has a pointer receiver, and Cat is not a pointer.

    If you change Cat to *Cat, it works:

    var same_cat *Cat = zoo.GetAnimal().(*Cat)
    
  2. The error pretty much says it all, too.

     append(zoo.animals, cat)
    

    You're appending cat to zoo.animals (evaluating), then throwing away the result, because there's nothing on the left side. You probably want to do this instead:

    zoo.animals = append(zoo.animals, cat)
    

One other side note: When you're assigning to a variable directly, there's no need to specify the type, because Go can determine it for you. Therefore

var same_cat Cat = zoo.GetAnimal().(Cat)

would be better expressed as:

var same_cat = zoo.GetAnimal().(Cat)

or also:

same_cat := zoo.GetAnimal().(Cat)
like image 51
Flimzy Avatar answered Oct 23 '22 06:10

Flimzy