英文:
How do I iterate through a slice of interfaces?
问题
还是对Go语言比较新手。我正在尝试实现这里对我之前问题的建议中提到的答案。在这种情况下,我有一个动物接口和一堆动物结构体。我想能够迭代每个动物并获取它的语言。我尝试了一个指针列表,但是我一直得到一个错误:"y.language未定义(类型animal没有字段或方法language)":
package main
import "fmt"
type animal interface {
speak()
}
type dog struct{
language string
}
func (d *dog) speak() {
d.language = "woof"
}
var n = []animal{
&dog{},
}
func main() {
for _, w := range n{
x := &dog{}
fmt.Println(x)
x.speak()
fmt.Println(x.language) // 这个可以工作
fmt.Println(w)
y := w
y.speak()
fmt.Println(y.language) // 但这个不行...为什么??
}
}
编辑 #1:为了让我的问题更清楚:为什么 x := &dog{} 能工作,但 y := w 不行?
编辑 #2:对新手没有爱心;(
英文:
Still new to Go. I'm trying to implement the answer as suggested here to my previous question. In this case I have an animal interface and a bunch of animal structs. I want to be able to iterate over each animal & get it's language. I've tried a list of pointers but I keep getting an error "y.language undefined (type animal has no field or method language)":
package main
import "fmt"
type animal interface {
speak()
}
type dog struct{
language string
}
func (d *dog) speak() {
d.language = "woof"
}
var n = []animal{
&dog{},
}
func main() {
for _, w := range n{
x := &dog{}
fmt.Println(x)
x.speak()
fmt.Println(x.language) // this works
fmt.Println(w)
y := w
y.speak()
fmt.Println(y.language) // but this doesn't...why??
}
}
EDIT #1: To make my question clearer: Why does x := &dog{} work but y := w does not?
EDIT #2: No love for newbs ;(
答案1
得分: 3
错误是正确的。y := w
声明 y
为 animal
类型(因为你的 n
切片是 animal
类型)。由于你的 animal
接口不包含 language
... 它不知道该怎么做,因此会出现错误。
你可以使用类型断言来断言它实际上是一个 dog
指针:
fmt.Println(y.(*dog).language)
..然而,我不确定你想要实现什么。
当你引入一个没有 language
属性的 cat
时,你的结构就会出问题。因此,这也会有类似的问题(希望能够展示出你的问题所在):
type cat struct{
}
func (c *cat) speak() {
// 什么都不做
}
回答你的问题“如何实现一个接口切片?” - 你需要在接口中添加你需要的任何内容,以便以“通用”的方式处理这些项。这意味着将 language
属性转换为 Language()
方法,并通过每个实现 animal
接口的对象返回它。
英文:
The error is correct. y := w
is declaring y
to be of type animal
(as your n
slice is of type animal
). As your animal
interface does not contain language
... it doesn't know what to do and as such it is an error.
You can assert that it is actually a dog
pointer by using a type assertion:
fmt.Println(y.(*dog).language)
..however, I am not sure what you're trying to achieve.
Your structure breaks when you introduce a cat
that doesn't have a language
property too. As such, this will also have similar problems (and hopefully demonstrate where your issue lies):
type cat struct{
}
func (c *cat) speak() {
// do nothing
}
The answer to your question of "How do I implement a slice of interfaces?" - you need to add whatever you require to the interface in order to process the items "generically". This means turning the language
property into a Language()
method and returning it via each individual object that implements the animal
interface.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论