我正在浏览,这模块让我思考,似乎每次你通过切片下界来修改视图时,切片的容量和长度都会减少。但是,正如前面所述,切片创建的底层数组不会被更改。
我将示例代码简化如下:
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
s = s[6:]
fmt.Println(cap(s), len(s), s)
}这个打印:0 0 [],意思是这个片段现在完全没用了。
但是,数组是未更改的,数组仍然是(为了可视化):
[2, 3, 5, 7, 11, 13]并由s引用,这意味着它不会被收集到垃圾。
所以我的问题是,这是切片的副作用,还是预期的/首选的行为?第二,是否有办法将视图恢复到原来的水平?(显示[2, 3, 5, 7, 11, 13])
发布于 2018-07-28 22:45:58
你好像很了解围棋片。
Go片被实现为struct
type slice struct {
array unsafe.Pointer
len int
cap int
}它是底层数组的视图。
例如,
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
fmt.Println("s", cap(s), len(s), s)
t := s[cap(s):]
fmt.Println("s", cap(s), len(s), s)
fmt.Println("t", cap(t), len(t), t)
t = s
fmt.Println("s", cap(s), len(s), s)
fmt.Println("t", cap(t), len(t), t)
}操场:https://play.golang.org/p/i-gufiJB-sP
输出:
s 6 6 [2 3 5 7 11 13]
s 6 6 [2 3 5 7 11 13]
t 0 0 []
s 6 6 [2 3 5 7 11 13]
t 6 6 [2 3 5 7 11 13]在没有对基础数组的任何元素的引用(指针)之前,将不会垃圾收集基础数组。
例如,
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
fmt.Println("s", cap(s), len(s), s, &s[0])
t := s
// the slice s struct can be garbage collected
// the slice s underlying array can not be garbage collected
fmt.Println("t", cap(t), len(t), s, &t[0])
p := &t[0]
// the slice t struct can be garbage collected
// the slice t (slice s) underlying array can not be garbage collected
fmt.Println("p", p, *p)
// the pointer p can be garbage collected
// the slice t (and s) underlying array can be garbage collected
}操场:IS7S3QE
输出:
s 6 6 [2 3 5 7 11 13] 0x10458000
t 6 6 [2 3 5 7 11 13] 0x10458000
p 0x10458000 2阅读:
发布于 2018-07-28 23:28:17
至于你的第二个问题,是的,你可以恢复原来,但只有非常黑暗的魔法反射和不安全。
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s)) //extract SliceHeader
arr := *(*[6]int)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s)).Data)) //restore array data它不能安全或可移植地使用,其表示形式可能在以后的版本中更改。
不要在生产中使用这个。
https://stackoverflow.com/questions/51575627
复制相似问题