接口和类型的问题

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

issue with interfaces and types

问题

有人能解释一下为什么在将切片传递给可变参数函数时,鸭子类型不起作用吗?

下面的情况1和情况2似乎是可以工作的,但是情况3中,切片被初始化,然后将解引用的切片传递给接受接口的函数。

错误信息是:cannot use gophers (type []Gopher) as type []Animal in argument to runForest

package main

import (
	"fmt"
)

type Animal interface {
	Run() string
}

type Gopher struct {
}

func (g Gopher) Run() string {
	return "Waddle.. Waddle"
}

func runForest(animals ...Animal) {
	for _, animal := range animals {
		fmt.Println(animal.Run())
	}
}

func main() {

	//可以工作
	runForest(Gopher{})

	//可以工作
	runForest(Gopher{}, Gopher{})

	//不可以工作
	gophers := []Gopher{{}, {}}
	runForest(gophers...)
}
英文:

Can someone please explain as to why duck typing does not work when a slice is passed to the variadic function.
Cases 1 and 2 as indicated below seems to work, but case-3 below initializes a slice and thereafter passes the dereferenced slice to the function that accepts the interface.

The error message is : cannot use gophers (type []Gopher) as type []Animal in argument to runForest

package main
    
    import (
    	"fmt"
    )
    
    type Animal interface {
    	Run() string
    }
    
    type Gopher struct {
    }
    
    func (g Gopher) Run() string {
    	return "Waddle.. Waddle"
    }
    
    func runForest(animals ...Animal) {
    	for _, animal := range animals {
    		fmt.Println(animal.Run())
    	}
    }
    
    func main() {
        
        //works
        runForest(Gopher{})

        //works
        runForest(Gopher{},Gopher{})
        
        // does not work
        gophers := []Gopher{{},{}}
    	runForest(gophers...)
    }

答案1

得分: 2

如Volker在评论中提到的,切片不能像它们的元素那样隐式转换。一个Gopher可以像一个Animal一样嘎嘎叫,但一个[]Gopher不能像一个[]Animal一样嘎嘎叫。

使其正常工作的最小更改如下:

func main() {
    gophers := []Gopher{{}, {}}
    out := make([]Animal, len(gophers))
    for i, val := range gophers {
        out[i] = Animal(val)
    }
    runForest(out...)
}
英文:

As Volker mentions in the comments, slices can't be implicitly converted the way their elements can. A Gopher can quack like an Animal, but a []Gopher can't quack like an []Animal.

The minimal change to get this working is:

func main() {
    gophers := []Gopher{{}, {}}
    out := make([]Animal, len(gophers))
    for i, val := range gophers {
        out[i] = Animal(val)
    }
    runForest(out...)
}

huangapple
  • 本文由 发表于 2016年2月17日 05:25:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/35443292.html
匿名

发表评论

匿名网友

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

确定