理解Go语言中接口和指针的类型断言

huangapple go评论141阅读模式
英文:

Understanding type assertions with interfaces and pointers in Go

问题

让我们考虑以下程序:

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)
}

现在,请注意最后一行的a.Compare(&b)。在这里,我传递了一个指向Apple的指针。这样做是正确的,但请注意,我的Compare函数并没有接受指针(y Fruit)

现在,如果我将最后一行改为a.Compare(b),那么它会给我以下错误:

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

这里发生了什么?

英文:

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 ing on here?

答案1

得分: 3

由于这个答案中所述的原因,Apple没有实现Fruit,但*Apple有。如果你在Apple上定义Color(而不是*Apple),代码将会编译通过:

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))
}
英文:

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))
}

huangapple
  • 本文由 发表于 2017年4月23日 18:44:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/43570119.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定