treecoder
treecoder

Reputation: 45081

Understanding type assertions with interfaces and pointers in Go

Let's consider the following program

type Fruit interface {
    Color() string
}

type Apple struct {
    color string
}

func (x *Apple) Color() string {
    return x.color
}

func (x *Apple) Compare(y Fruit) bool {
    _, ok := y.(*Apple)

    if ok {
        ok = y.Color() == x.Color()
    }

    return ok
}

func main() {
    a := Apple{"red"}
    b := Apple{"green"}

    a.Compare(&b)
}

Now, note the last line that says a.Compare(&b). Here I am passing a pointer to Apple. This works correctly, but note that my Compare function does NOT accept the pointer (y Fruit).

Now if I change the last line to say a.Compare(b) then it gives me the following error:

cannot use b (type Apple) as type Fruit in argument to a.Compare: Apple does not implement Fruit (Color method has pointer receiver)

What is [go]ing on here?

Upvotes: 2

Views: 487

Answers (1)

fuglede
fuglede

Reputation: 18201

For reasons outlined in this answer, Apple does not implement Fruit, but *Apple does. If you define Color on Apple (instead of *Apple), the code compiles:

package main

import (
    "fmt"
)
type Fruit interface {
    Color() string
}

type Apple struct {
    color string
}

func (x Apple) Color() string {
    return x.color
}

func (x Apple) Compare(y Fruit) bool {
    _, ok := y.(Apple)

    if ok {
        ok = y.Color() == x.Color()
    }

    return ok
}

func main() {
    a := Apple{"red"}
    b := Apple{"green"}

    fmt.Println(a.Compare(b))
}

Upvotes: 3

Related Questions