Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何清除围棋中的一片?_Arrays_Go_Slice - Fatal编程技术网

Arrays 如何清除围棋中的一片?

Arrays 如何清除围棋中的一片?,arrays,go,slice,Arrays,Go,Slice,在Go中清除切片的适当方式是什么 以下是我在网上找到的: 这是正确的吗 为了澄清这一点,缓冲区被清除,以便可以重复使用 例如bytes包中的函数 请注意,Reset只调用Truncate(0)。因此,在这种情况下,第70行将评估: b、 buf=b.buf[0:0] //Truncate丢弃缓冲区中除前n个未读字节以外的所有字节。 60//如果n为负数或大于缓冲区的长度,则会出现恐慌。 61 func(b*缓冲区)截断(n int){ 62 b.lastRead=opInvalid 63开关{

在Go中清除切片的适当方式是什么

以下是我在网上找到的:

这是正确的吗

为了澄清这一点,缓冲区被清除,以便可以重复使用

例如bytes包中的函数

请注意,Reset只调用Truncate(0)。因此,在这种情况下,第70行将评估: b、 buf=b.buf[0:0]

//Truncate丢弃缓冲区中除前n个未读字节以外的所有字节。
60//如果n为负数或大于缓冲区的长度,则会出现恐慌。
61 func(b*缓冲区)截断(n int){
62 b.lastRead=opInvalid
63开关{
64例n<0 | | n>b.Len()
65死机(“bytes.Buffer:截断超出范围”)
66情况n==0:
67//重用缓冲区空间。
68 b.off=0
69      }
70 b.buf=b.buf[0:b.off+n]
71  }
72
73//Reset重置缓冲区,使其没有内容。
74//b.Reset()与b.Truncate(0)相同。
75 func(b*缓冲区)Reset(){b.Truncate(0)}

这完全取决于您对“清除”的定义。其中一个有效的方法当然是:

slice = slice[:0]
但有一个陷阱。如果切片元素为T型:

var slice []T
然后通过上述“技巧”将
len(slice)
强制为零,不会使任何元素

slice[:cap(slice)]

有资格进行垃圾收集。在某些情况下,这可能是最佳方法。但这也可能是“内存泄漏”的原因—内存未使用,但可能可访问(在“切片”重新切片后),因此不可“回收”垃圾。

将切片设置为
nil
是清除切片的最佳方法nil片表现良好,将该片设置为
nil
将向垃圾收集器释放底层内存

印刷品

letters =  [a b c d]
4
4
0 a
1 b
2 c
3 d
letters =  []
0
0
letters =  [e]
1
1
0 e
请注意,切片可以很容易地进行别名处理,以便两个切片指向相同的底层内存。设置为
nil
将删除该别名


不过,这种方法将容量更改为零。

出于我自己的目的,我研究了一下这个问题;我有一个结构片(包括一些指针),我想确保我得到了它的权利;在这个帖子上结束,并想分享我的结果

为了练习,我在操场上做了一些小动作:

以下哪项评估:

package main

import "fmt"

type Blah struct {
    babyKitten int
    kittenSays *string
}

func main() {
    meow := "meow"
    Blahs := []Blah{}
    fmt.Printf("Blahs: %v\n", Blahs)
    Blahs = append(Blahs, Blah{1, &meow})
    fmt.Printf("Blahs: %v\n", Blahs)
    Blahs = append(Blahs, Blah{2, &meow})
    fmt.Printf("Blahs: %v\n", Blahs)
    //fmt.Printf("kittenSays: %v\n", *Blahs[0].kittenSays)
    Blahs = nil
    meow2 := "nyan"
    fmt.Printf("Blahs: %v\n", Blahs)
    Blahs = append(Blahs, Blah{1, &meow2})
    fmt.Printf("Blahs: %v\n", Blahs)
    fmt.Printf("kittenSays: %v\n", *Blahs[0].kittenSays)
}
按原样运行该代码将显示“meow”和“meow2”变量的相同内存地址:

Blahs: []
Blahs: [{1 0x1030e0c0}]
Blahs: [{1 0x1030e0c0} {2 0x1030e0c0}]
Blahs: []
Blahs: [{1 0x1030e0f0}]
kittenSays: nyan
我认为这证实了结构是垃圾收集的。奇怪的是,取消注释已注释的打印行将为meows生成不同的内存地址:

Blahs: []
Blahs: [{1 0x1030e0c0}]
Blahs: [{1 0x1030e0c0} {2 0x1030e0c0}]
kittenSays: meow
Blahs: []
Blahs: [{1 0x1030e0f8}]
kittenSays: nyan
我认为这可能是由于打印在某种程度上被延迟(?),但一些内存管理行为的有趣说明,以及对以下内容的再次投票:

[]MyStruct = nil

快速测试:似乎表明它会工作(不会改变容量,但会截断长度)有趣。有没有其他方法可以在保持底层容量不变的情况下从片的底层数组中删除所有元素?@ChrisWeber:只需迭代底层数组并将所有元素设置为新的值即可value@jnml,我确实希望重用该片(以及底层阵列存储),因此我不会不断地分配新片(带阵列)。我编辑了我的问题,以澄清并展示标准库中的一些示例代码。我是新手。请您解释一下为什么这是一种最佳方法,好吗?请提前感谢。您确定片大小重置会导致内存泄漏吗?感谢您的回复,我无法复制它。请查看我的更新ould.我正在清除片以便重用。因此我不一定希望底层内存释放到GC,因为我只需要再次分配它。这是我搜索的!)基于标题“如何在Go中清除片?”这是一个安全的答案,应该是可以接受的答案。一个完美的答案应该是将最初接受的答案和这个答案结合起来,这样人们就可以自己决定了。
append
ing到
nil
slice在Go?@alediaferia自Go 1.0以来一直有效。当然,很好的详细示例。谢谢这并不表明meo1和meow2的内存地址是相同的:
0x1030e0c0
不等于
0x1030e0f0
(前者以
c0
结尾,后者以
f0
结尾)。这里同意@carbocation,这些内存地址是不一样的。我并不声称能够更好地解释这里发生了什么,但这并不能作为我的证据。我确实在
meow2
每次运行的地址中看到了相同的8字节差异。。。
Blahs: []
Blahs: [{1 0x1030e0c0}]
Blahs: [{1 0x1030e0c0} {2 0x1030e0c0}]
Blahs: []
Blahs: [{1 0x1030e0f0}]
kittenSays: nyan
Blahs: []
Blahs: [{1 0x1030e0c0}]
Blahs: [{1 0x1030e0c0} {2 0x1030e0c0}]
kittenSays: meow
Blahs: []
Blahs: [{1 0x1030e0f8}]
kittenSays: nyan
[]MyStruct = nil