未实现,方法类型错误

给定以下 Go 代码:


package main


type CatToy interface {

    Rattle() string

}


type Cat struct {

}


func (cat *Cat) Play(catToy CatToy) {

    println("The cat is playing!", catToy.Rattle())

}


type DogToy interface {

    Roll() string

}


type Dog struct {

}


func (dog *Dog) Play(dogToy DogToy) {

    println("The dog is playing!", dogToy.Roll())

}


type SuperToy struct {

}


func (toy *SuperToy) Rattle() string {

    return "Rattle!!!"

}


func (toy *SuperToy) Roll() string {

    return "Rolling..."

}


type Pet interface {

    Play(toy interface{})

}


func main() {

    cat := &Cat{}

    dog := &Dog{}

    superToy := &SuperToy{}


    // Working

    cat.Play(superToy)

    dog.Play(superToy)


    // Not Working

    pets := []Pet{cat, dog}

    for _, pet := range pets {

        pet.Play(superToy)

    }

}

我收到这些错误:


# command-line-arguments

./main.go:65:16: cannot use cat (type *Cat) as type Pet in array or slice literal:

    *Cat does not implement Pet (wrong type for Play method)

        have Play(CatToy)

        want Play(interface {})

./main.go:65:21: cannot use dog (type *Dog) as type Pet in array or slice literal:

    *Dog does not implement Pet (wrong type for Play method)

        have Play(DogToy)

        want Play(interface {})

实现SuperToy了CatToy和DogToy。但是,当我创建一个接口Pet作为参数的接口时,我得到一个错误。我可以知道我怎样才能得到一个里面有猫和狗的数组/切片吗?我想遍历这个切片并为每个切片调用一个函数。我还想保留CatToy和DogToy接口。我也可以删除Pet界面。


更多信息:未来我更有可能添加更多pets。我认为我不会添加更多操作,例如Play.


ibeautiful
浏览 96回答 3
3回答

万千封印

我明白你想做什么,但这是不可能的:你的Cat和Dog类型没有实现Pet接口,因为它们的Play方法采用不同的类型,所以你不能只用Play你的SuperToy.要解决此问题,您需要创建一个Toy接口,该接口同时具有Roll和Rattle方法以及 make Pet.Play,Cat.Play并将Dog.Play此接口作为参数。package maintype Cat struct {}func (cat *Cat) Play(catToy Toy) {    println("The cat is playing!", catToy.Rattle())}type Dog struct {}func (dog *Dog) Play(dogToy Toy) {    println("The dog is playing!", dogToy.Roll())}type Toy interface {    Roll() string    Rattle() string}type SuperToy struct {}func (toy *SuperToy) Rattle() string {    return "Rattle!!!"}func (toy *SuperToy) Roll() string {    return "Rolling..."}type Pet interface {    Play(toy Toy)}func main() {    cat := &Cat{}    dog := &Dog{}    superToy := &SuperToy{}    // Working    cat.Play(superToy)    dog.Play(superToy)    // Not Working    pets := []Pet{cat, dog}    for _, pet := range pets {        pet.Play(superToy)    }}给出输出The cat is playing! Rattle!!!The dog is playing! Rolling...The cat is playing! Rattle!!!The dog is playing! Rolling...

皈依舞

您可以让 Play 方法接受一个interface{},然后在方法内进行类型断言:func (dog *Dog) Play(toy interface{}) {    dogToy, isDogToy := toy.(DogToy)    if !isDogToy {        println("The dog does not know what to do with this toy!")        return    }    println("The dog is playing!", dogToy.Roll())}Go Playground 上的完整可执行示例:https://play.golang.org/p/LZZ-HqpzR-Z

12345678_0001

这是另一个可行的解决方案:package maintype CatToy interface {    Rattle() string}type Cat struct {    Toy CatToy}func (cat *Cat) Play() {    println("The cat is playing!", cat.Toy.Rattle())}type DogToy interface {    Roll() string}type Dog struct {    Toy DogToy}func (dog *Dog) Play() {    println("The dog is playing!", dog.Toy.Roll())}type SuperToy struct {}func (toy *SuperToy) Rattle() string {    return "Rattle!!!"}func (toy *SuperToy) Roll() string {    return "Rolling..."}type Pet interface {    Play()}func main() {    superToy := &SuperToy{}    cat := &Cat{superToy}    dog := &Dog{superToy}    // Working    cat.Play()    dog.Play()    // Working also    pets := []Pet{cat, dog}    for _, pet := range pets {        pet.Play()    }}该解决方案使Cat + CatToy和Dog + DogToy独立于main + SuperToy. 这允许提取以分离包。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go