从接口类型转换为实际类型的不可能的类型断言

use*_*195 7 go

我有两个错误,

一个.不可能的类型断言.我们可以从接口类型转换为实际的类型对象

湾 不确定评估的含义是什么,但未使用

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]
}
Run Code Online (Sandbox Code Playgroud)

测试

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)
Run Code Online (Sandbox Code Playgroud)

游乐场

Fli*_*mzy 10

  1. 错误消息几乎说明了一切:

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

    Cat没有实现IAnimal,因为Speak(IAnimal接口的一部分)有一个指针接收器,而Cat不是一个指针.

    如果更改Cat*Cat,它的工作原理:

    var same_cat *Cat = zoo.GetAnimal().(*Cat)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 错误几乎说明了这一切.

     append(zoo.animals, cat)
    
    Run Code Online (Sandbox Code Playgroud)

    要追加catzoo.animals(评估),然后扔掉的结果,因为没有什么左侧.您可能想要这样做:

    zoo.animals = append(zoo.animals, cat)
    
    Run Code Online (Sandbox Code Playgroud)

另外注意:当你直接分配变量时,不需要指定类型,因为Go可以为你确定它.因此

var same_cat Cat = zoo.GetAnimal().(Cat)
Run Code Online (Sandbox Code Playgroud)

会更好地表达为:

var same_cat = zoo.GetAnimal().(Cat)
Run Code Online (Sandbox Code Playgroud)

或者:

same_cat := zoo.GetAnimal().(Cat)
Run Code Online (Sandbox Code Playgroud)

  • `var cat IAnimal = &Cat{}` <-- 您仍在将 `IAnimal` 设置为指针,然后尝试将其断言为非指针。您需要始终保持一致。 (2认同)