The answer to this is probably pretty obvious, but I'm asking anyways because I failed to find a good explanation for this.
I have two examples that I've made, they do pretty much the same thing, however, the first one uses int's and the other one is using interfaces:
Interface: https://play.golang.org/p/yb2oVaOJGF
Int: https://play.golang.org/p/_z8Mm0II41
Could someone please explain why they produce different output?
In the case where Apple and Orange are defined as interface{}
, the type switch is satisfied by anything that implements that interface.
For the empty interface, that is anything at all, and it takes the first case that matches.
When Apple and Orange are "aliases" for a non-interface type (int), only a variable that is explicitly an Apple or Orange can satisfy the type switch.
Because you are defining the Apple and Orange types to an empty interface they are satisfied by anything.
The empty interface is in essence nothing specific.
Everything in the first example can be asserted as the int type neither Apple or Oranges.
Look at this small change to your first example's code.
package main
import (
"fmt"
"log"
)
type Apple interface{}
type Orange interface{}
type Basket struct {
Fruit interface{}
}
func getFruites(basket Basket) {
switch t := basket.Fruit.(type) {
case int:
fmt.Println("empty interfaces are satisfying an int")
case Apple:
apples, ok := t.(int)
if !ok {
log.Panic("Rotten apples!")
}
fmt.Println("Apples:", apples)
case Orange:
oranges, ok := t.(int)
if !ok {
log.Panic("Rotten oranges!")
}
fmt.Println("Oranges:", oranges)
}
}
func main() {
appleBasket := Basket{
Fruit: Apple(10),
}
getFruites(appleBasket)
orangeBasket := Basket{
Fruit: Orange(10),
}
getFruites(orangeBasket)
}