关于 go 可变参数解包的问题

2020-12-25 16:28:17 +08:00
 asAnotherJack

如图,我想往一个接口 slice 里,append 进一个 impl slice 的所有元素,为什么单个 append 就可以,用...的方式就不行啊,这种我只能 for 循环依次 append 了吗?求大佬解惑

type ISayHi interface {
	Hi()
}

type SayHiImpl struct {

}

func (s *SayHiImpl) Hi() {
	fmt.Println("Hi")
}

func main() {
	s := make([]ISayHi, 0)
	impls := make([]*SayHiImpl, 0)
	impls = append(impls, &SayHiImpl{})
	s = append(s, impls[0])
	s = append(s, impls...)

}
2467 次点击
所在节点    Go 编程语言
9 条回复
assiadamo
2020-12-25 16:31:21 +08:00
看上去只能循环解引用加进去
vasil
2020-12-25 16:33:48 +08:00
s 和 impls 的类型不一致
westoy
2020-12-25 16:42:55 +08:00
s = append(s, s[:]...)
gochat
2020-12-25 16:48:05 +08:00
```go
type ISayHi interface {
Hi()
}

type SayHiImpl struct {
}

func (s *SayHiImpl) Hi() {
fmt.Println("Hi")
}

func main() {
s := make([]ISayHi, 0)
impls := make([]ISayHi, 0)
impls = append(impls, &SayHiImpl{})
s = append(s, impls[0])
s = append(s, impls...)
}
```

这么玩
asAnotherJack
2020-12-25 16:53:01 +08:00
@gochat #4 嗯,现在就是这么搞的,就是觉得这种 单个元素能 append,slice 解包不能 append 有点反直觉,头大
pigmen
2020-12-25 16:55:49 +08:00
mark 下不太懂,用什么单个可以,unpack 不行
keepeye
2020-12-25 16:56:25 +08:00
keepeye
2020-12-25 16:58:46 +08:00
简单来说,append 需要编译器支持,而编译器不支持复杂的转换。比如 []*SayHiImpl 转换成 []ISayHi 需要 O(N)的复杂度,是不支持的.
至于单个为什么可以,因为转换单个只要 O(1)
ZSeptember
2020-12-25 17:06:51 +08:00
go 不支持 Covariance 。
append 的第二个参数是 []ISayHi,[]*SayHiImpl 并不是[]ISayHi 的子类型。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/738956

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX