在通常编码中,我们很多用到的切片都是从数组上截取的,但是一些朋友可能发现,类似于
var a = [12]int{}[:] //错误!会报错!
这样写是会报错:invalid operation [12]int{}[:] (slice of unaddressable value)
为什么会这样呢?
因为切片是需要数组的地址才能实现切片,而在[12]int{}没有赋值给变量时,它是没有地址的。
知道原因后就很容易解决了,解决思路如下:
解法一:
直接切片数组地址:
var a = (&[12]int{})[:] //正确,可以通过编译。
这样写是可以通过编译的,但是没什么实际作用,因为能实现同样功能的make明显更好用:
var a = make([]int,12) //通常写法
解法二:
将数组赋值给变量之后再切片:
var a = [12]int{}
var b = a[:] //正确,可以通过编译。
当完成赋值后,就能获取到数组的地址,自然也就可以切片了,这个解决方法是最好的,因为对于某些返回数组的方法函数(比如Golang中的生成MD5方法)来说,这是能把返回的数组进行切片的最简便的方法。
有人说不能参考解法一,用&对返回的数组进行取址吗?比如:
func main() {
var a = (&test())[:] //错误!会报错!
fmt.Println(a)
}
func test() [12]int {
return [12]int{}
}
很遗憾,解法一的思路是直接生成地址,而方法函数返回的数组,在赋值以前是没有地址的,自然是无法取址,所以最好的解决方法就是将返回的数据赋值给一个变量,再对变量进行切片。
那又有人问了,那如果方法函数返回的是数组的地址(即对应指针类型),能直接进行切片吗?比如:
func main() {
var a = test()[:] //正确,可以通过编译。
fmt.Println(a)
}
func test() *[12]int {
return &[12]int{}
}
当然可以,这才是解法一的思路,对于数组的地址(即对应指针类型),切片操作是有效的,可以直接在方法函数上直接进行切片。