你如何清理Go中的一个片段? [英] How do you clear a slice in Go?

查看:131
本文介绍了你如何清理Go中的一个片段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



以下是我在 go论坛

  // test.go 
package main

import(
fmt


func main(){
letters:= [] string {a,b,c,d}
fmt.Println(cap(letters))
fmt.Println(len字母))
//清除切片
letters = letters [:0]
fmt.Println(cap(letters))
fmt.Println(len(letters))
}

这是否正确?

<为了澄清,缓冲区已被清除,因此可以重新使用。



一个例子是 Buffer.Truncate 函数。



注意Reset只调用Truncate(0)。所以看起来在这种情况下,第70行会计算:
b.buf = b.buf [0:0]

http://golang.org/src/pkg/bytes/buffer.go

  //截断丢弃除缓冲区前n个未读字节外的所有内容。 
60 //如果n为负数或大于缓冲区的长度,会发生混乱。
61 func(b * Buffer)Truncate(n int){
62 b.lastRead = opInvalid
63 switch {
64 case n< 0 || n> b.Len():
65 panic(bytes.Buffer:truncation out of range)
66 case 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)相同。
func(b * Buffer)Reset(){b.Truncate(0)}


解决方案

这一切都取决于你对'明确'的定义是什么。其中一个有效的肯定是:

  slice = slice [:0] 

但有一个问题。如果切片元素的类型为T:

  var slice [] T 

然后执行 len(slice)为零,通过上述技巧, doesn 't 使任何元素

  slice [:cap(slice)] 

符合垃圾回收的条件。在某些情况下,这可能是最佳方法。但它也可能是内存泄漏的原因 - 内存不被使用,但可能可以访问(在重新切片之后),因此不是垃圾收集。

What is the appropriate way to clear a slice in Go?

Here's what I've found in the go forums:

// test.go
package main

import (
    "fmt"
)

func main() {
    letters := []string{"a", "b", "c", "d"}
    fmt.Println(cap(letters))
    fmt.Println(len(letters))
    // clear the slice
    letters = letters[:0]
    fmt.Println(cap(letters))
    fmt.Println(len(letters))
}

Is this correct?

To clarify, the buffer is cleared so it can be reused.

An example is Buffer.Truncate function in the bytes package.

Notice that Reset just calls Truncate(0). So it appears that in this case line 70 would evaluate: b.buf = b.buf[0 : 0]

http://golang.org/src/pkg/bytes/buffer.go

// Truncate discards all but the first n unread bytes from the buffer.
60  // It panics if n is negative or greater than the length of the buffer.
61  func (b *Buffer) Truncate(n int) {
62      b.lastRead = opInvalid
63      switch {
64      case n < 0 || n > b.Len():
65          panic("bytes.Buffer: truncation out of range")
66      case n == 0:
67          // Reuse buffer space.
68          b.off = 0
69      }
70      b.buf = b.buf[0 : b.off+n]
71  }
72  
73  // Reset resets the buffer so it has no content.
74  // b.Reset() is the same as b.Truncate(0).
75  func (b *Buffer) Reset() { b.Truncate(0) }

解决方案

It all depends on what is your definition of 'clear'. One of the valid ones certainly is:

slice = slice[:0]

But there's a catch. If slice elements are of type T:

var slice []T

then enforcing len(slice) to be zero, by the above "trick", doesn't make any element of

slice[:cap(slice)]

eligible for garbage collection. This might be the optimal approach in some scenarios. But it might also be a cause of "memory leaks" - memory not used, but potentially reachable (after re-slicing of 'slice') and thus not garbage "collectable".

这篇关于你如何清理Go中的一个片段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆