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))
// clear the slice
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
// 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) }
그것은 모두 '명확한'에 대한 당신의 정의에 달려 있습니다. 유효한 것 중 하나는 다음과 같습니다.
slice = slice[:0]
그러나 캐치가 있습니다. 슬라이스 요소가 T 유형 인 경우 :
var slice []T
다음 시행 len(slice)
은 "트릭"이상으로, 영으로, 하지 의 요소를 만들
slice[:cap(slice)]
가비지 수집에 적합합니다. 일부 시나리오에서는 이것이 최적의 방법 일 수 있습니다. 그러나 "메모리 누수"의 원인 일 수도 있습니다. 메모리가 사용되지 않지만 잠재적으로 접근 할 수 있으며 ( '슬라이스'를 다시 슬라이스 한 후) 가비지 "수집 가능"이 아닙니다.
슬라이스를 설정하는 것이 슬라이스를 nil
지우는 가장 좋은 방법입니다. nil
이동중인 슬라이스는 완벽하게 작동하며 슬라이스를 설정 nil
하면 기본 메모리가 가비지 콜렉터에 해제됩니다.
package main
import (
"fmt"
)
func dump(letters []string) {
fmt.Println("letters = ", letters)
fmt.Println(cap(letters))
fmt.Println(len(letters))
for i := range letters {
fmt.Println(i, letters[i])
}
}
func main() {
letters := []string{"a", "b", "c", "d"}
dump(letters)
// clear the slice
letters = nil
dump(letters)
// add stuff back to it
letters = append(letters, "e")
dump(letters)
}
인쇄물
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
해당 앨리어싱을 제거하는 설정 입니다.
이 방법은 용량을 0으로 변경합니다.
I was looking into this issue a bit for my own purposes; I had a slice of structs (including some pointers) and I wanted to make sure I got it right; ended up on this thread, and wanted to share my results.
To practice, I did a little go playground: https://play.golang.org/p/9i4gPx3lnY
which evals to this:
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)
}
Running that code as-is will show the same memory address for both "meow" and "meow2" variables as being the same:
Blahs: []
Blahs: [{1 0x1030e0c0}]
Blahs: [{1 0x1030e0c0} {2 0x1030e0c0}]
Blahs: []
Blahs: [{1 0x1030e0f0}]
kittenSays: nyan
which I think confirms that the struct is garbage collected. Oddly enough, uncommenting the commented print line, will yield different memory addresses for the meows:
Blahs: []
Blahs: [{1 0x1030e0c0}]
Blahs: [{1 0x1030e0c0} {2 0x1030e0c0}]
kittenSays: meow
Blahs: []
Blahs: [{1 0x1030e0f8}]
kittenSays: nyan
I think this may be due to the print being deferred in some way (?), but interesting illustration of some memory mgmt behavior, and one more vote for:
[]MyStruct = nil
참고URL : https://stackoverflow.com/questions/16971741/how-do-you-clear-a-slice-in-go
'Programing' 카테고리의 다른 글
“잠금 대기 시간 초과를 초과했습니다. (0) | 2020.07.22 |
---|---|
const는 C ++ 11에서 스레드 안전을 의미합니까? (0) | 2020.07.22 |
html 루비 코드 주위에 link_to를 어떻게 래핑합니까? (0) | 2020.07.21 |
MySQL에서 값을 NULL로 설정 (0) | 2020.07.21 |
Swift에서 프로그래밍 방식으로 UIButton 만들기 (0) | 2020.07.21 |