Can I convert a []T to an []interface{}?

Can I convert a []T to an []interface{}?

众所周知,在 Golang 中,interface 是一种抽象类型,相对于抽象类型的是具体类型(concrete type):int,string。interface{} 是一个空的 interface 类型,一个类型如果实现了一个 interface 的所有方法就说该类型实现了这个 interface,空的 interface 没有方法,所以可以认为所有的类型都实现了 interface{}。如果定义一个函数参数是 interface{} 类型,这个函数应该可以接受任何类型作为它的参数。

1
2
func changeType(v interface{}){    
}

既然空的 interface 可以接受任何类型的参数,那么一个 interface{}类型的 slice 是不是就可以接受任何类型的 slice ?看下面的代码:

1
2
3
4
5
6
7
8
9
10
func traverseSlice(vals []interface{}) { 
for _, val := range vals {
fmt.Println(val)
}
}

func main(){
nums := []string{"1", "2", "3"}
traverseSlice(nums)
}

不是说空的 interface 可以是任何类型吗?为何报了下面的错误?

image-20201209202110198

这个错误说明 go 没有自动把 []string 转换成 []interface{} ,所以出错了。go 不会对 类型是interface{} 的 slice 进行转换 。为什么 go 不帮我们自动转换? 在 golang 官方 blog 的 FAQ 中找到了对这个问题的解释,由于interface{} 会占用两部分存储空间,一个是自身的 methods 数据,一个是指向其存储值的指针,也就是 interface 变量存储的值,因而 slice []interface{} 其长度是固定的N*2,但是 []T 的长度是N*sizeof(T),用官方的解释就是两种类型在内存中的表现是不一样的。那该如何去转换呢?可以按照单个元素来转换:

1
2
3
4
5
6
7
8
9
10
11
12
import "fmt"

func main() {
t := []int{1, 2, 3, 4}
s := make([]interface{}, len(t))

for i, v := range t {
s[i] = v
}

fmt.Println(s)
}

image-20201209203108747

https://golang.org/doc/faq#convert_slice_of_interface 对这个问题的解释:

image-20201209203306491


-------------The End-------------

本文标题:Can I convert a []T to an []interface{}?

文章作者:cloud sjhan

发布时间:2020年12月09日 - 20:12

最后更新:2020年12月09日 - 20:12

原始链接:https://cloudsjhan.github.io/2020/12/09/Can-I-convert-a-T-to-an-interface/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

坚持原创技术分享,您的支持将鼓励我继续创作!
0%
;