In Go, how do I pass a slice of interface to something that expects slice of a different compatible interface?

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

In Go, how do I pass a slice of interface to something that expects slice of a different compatible interface?

问题

我有两个接口,AB。恰好A包含B。最后,我有一个A的具体实现(称为Impl),根据定义,它也实现了B

例如:

type A interface {
    Close() error
    Read(b []byte) (int, error)
}

type Impl struct {}
func (I Impl) Read(b []byte) (int, error) {
    fmt.Println("In read!")
    return 10, nil
}
func (I Impl) Close() error {
    fmt.Println("I am here!")
    return nil
}

由于A要求Read()方法,而Impl实现了A,它也满足io.Reader接口。

如果我尝试将单个A对象传递给期望io.Reader的函数,它可以正常工作。但是,如果我尝试将[]A切片传递给期望[]io.Reader的函数,它会失败。

例如:

func single(r io.Reader) {
    fmt.Println("in single")
}
func slice(r []io.Reader) {
    fmt.Println("in slice")
}
im := &Impl{}

// 正常工作
single(im)

// 失败!
list := []A{im}
slice(list)

如果我可以将A传递给single(r io.Reader)函数,为什么不能将[]A传递给slice(r []io.Reader)函数,如何进行修正?

实际实现代码请参考:https://play.golang.org/p/QOREQJTQhD,只需取消main()函数中的最后两行的注释,就会显示错误信息:

main.go:38: cannot use list (type []A) as type []io.Reader in argument to slice
英文:

I have two interfaces, A and B. It happens that A includes B. Finally, I have a concrete implementation of A (call it Impl), which, by definition, also implements B.

For example:

type A interface {
    Close() error
	Read(b []byte) (int, error)
}

type Impl struct {}
func (I Impl) Read(b []byte) (int, error) {
    fmt.Println("In read!")
    return 10, nil
}
func (I Impl) Close() error {
    fmt.Println("I am here!")
    return nil
}

Since A requires Read(), and Impl implements A, it also satisfies io.Reader.

If I try to pass individual items across functions, it works fine. But if I try slices of A to functions expecting io.Reader, it fails.

Example:

func single(r io.Reader) {
	fmt.Println("in single")
}
func slice(r []io.Reader) {
    fmt.Println("in slice")
}
im := &Impl{}

// works
single(im)

// FAILS!
list := []A{t}
slice(list)

If I can pass an A to single(r io.Reader), why can I not pass []A to slice(r []io.Reader), and how would I correct it?

Actual implementation at https://play.golang.org/p/QOREQJTQhD just uncomment the last two lines in main() and the error shows:

main.go:38: cannot use list (type []A) as type []io.Reader in argument to slice

答案1

得分: 3

我在这里问了类似的问题:https://stackoverflow.com/questions/38525874/in-go-how-can-i-make-a-generic-function-with-slices

不幸的是,这绝对是 Go 语言的一个弱点。你唯一的解决办法是创建一个新的类型为 []io.Reader 的切片,并将元素从 []A 复制过去。

英文:

I kind of asked something similar here
https://stackoverflow.com/questions/38525874/in-go-how-can-i-make-a-generic-function-with-slices

Sadly, this is definitely a weakness in Go. The only way for you to go around this is to make a new slice of type []io.Reader with elements from []A

huangapple
  • 本文由 发表于 2016年11月25日 21:20:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/40806029.html
匿名

发表评论

匿名网友

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

确定