无法将类型 []Child 作为类型 []Node 传递给函数作为参数。

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

cannot use children (type []Child) as type []Node in argument to func

问题

以下是你提供的代码的翻译:

这是我的测试代码

package main

import "fmt"

type Node interface {
    sayHello()
}

type Parent struct {
    Name string
}

type Child struct {
    Parent
    Age int
}

type Children []Child

func (p Parent) sayHello() {
    fmt.Printf("你好,我的名字是%s\n", p.Name)
}

func (p Child) sayHello() {
    fmt.Printf("你好,我的名字是%s,我%d岁\n", p.Name, p.Age)
}

func makeSayHello(n Node) {
    n.sayHello()
}

func sayHellos(list []Node) {
    for _, p := range list {
        makeSayHello(p)
    }
}

func main() {

    children := []Child{Child{Parent: Parent{Name: "Bart"}, Age: 8}, Child{Parent: Parent{Name: "Lisa"}, Age: 9}}

    for _, c := range children {
        c.sayHello()
    }

    makeSayHello(Parent{"Homer"})
    sayHellos([]Node{Parent{"Homer"}})
    sayHellos([]Node{Parent{"Homer"}, Child{Parent: Parent{"Maggy"}, Age: 3}})


    sayHellos(children) // 错误:无法将类型 []Child 作为类型 []Node 传递给 sayHellos
}

链接:https://play.golang.org/p/7IZLoXjlIK

我不明白。假设我有一个不可修改的 []Child,我想将其与接受 []Parent 的函数一起使用。为什么会出现类型错误?

如果我不能或不想通过更改

children := []Child{...}

children := []Node{...}

来解决这个问题,我该怎么办才能将 []Child 转换为 []Node?难道它不是已经是 []Node 吗?我尝试了 children.([]Node) 或 []Node(children),但没有成功...

英文:

Here is my test code

package main

import "fmt"

type Node interface {
	sayHello()
}

type Parent struct {
	Name string
}

type Child struct {
	Parent
	Age int
}

type Children []Child

func (p Parent) sayHello() {
	fmt.Printf("Hello my name is %s\n", p.Name)
}

func (p Child) sayHello() {
	fmt.Printf("Hello my name is %s and I'm %d\n", p.Name, p.Age)
}

func makeSayHello(n Node) {
	n.sayHello()
}

func sayHellos(list []Node) {
	for _, p := range list {
		makeSayHello(p)
	}
}

func main() {

	children := []Child{Child{Parent: Parent{Name: "Bart"}, Age: 8}, Child{Parent: Parent{Name: "Lisa"}, Age: 9}}

	for _, c := range children {
		c.sayHello()
	}

	makeSayHello( Parent{"Homer"} )
	sayHellos( []Node{Parent{"Homer"}} )
	sayHellos( []Node{Parent{"Homer"},Child{Parent:Parent{"Maggy"},Age:3}} )
	
	
	sayHellos( children )	// error : cannot use children (type []Child) as type []Node in argument to sayHellos
}

link https://play.golang.org/p/7IZLoXjlIK

I don't get it. Let's say I have a []Child I cannot modify and I want use it with un function accepting []Parent. Why do I have an type error ?

If I can't or don't want this solution by changing

children := []Child{...}

to

children := []Node{...}

What can I do to transform the []Child to []Node ? It is not already ? Do I have to do another []Node to copy my elements in ?
I naïvely try children.([]Node) or []Node(children) without success ...

答案1

得分: 1

一个结构体数组(比如[]Child)与一个接口数组(比如[]Node)在内存布局上有很大的区别。因此,Go语言不会隐式地将[]Child转换为[]Node,你需要自己进行转换:

nodes := make([]Node, len(children), len(children))
for i := range children {
    nodes[i] = children[i]
}
sayHellos(nodes)

顺便提一下,在你提供的示例中,直接调用sayHello会更高效:

for _, child := range children {
    child.sayHello()
}

可能这也是你在程序中应该做的事情。

英文:

An array of structs (such as []Child) has very different memory layout comparing to an array of interfaces (such as []Node). So Go doesn't do []Child to []Node conversion implicitly, you have to do it yourself:

nodes := make([]Node, len(children), len(children))
for i := range children {
	nodes[i] = children[i]
}
sayHellos(nodes)

BTW in the example you provided it would be more efficient to call sayHello directly:

for _, child := range children {
	child.sayHello()
}

Probably this is what you should do in your program as well.

huangapple
  • 本文由 发表于 2016年2月10日 19:59:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/35314649.html
匿名

发表评论

匿名网友

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

确定