问题描述
在Go中使用字符串的子字符串时,不会分配新内存。相反,子字符串的底层表示包含一个数据指针,它是原始字符串数据指针的偏移量。这意味着如果我有一个大字符串并希望跟踪一个小的子字符串,垃圾收集器将无法释放任何大字符串,直到我释放对较短子字符串的所有引用。
切片有类似的问题,但你可以通过使用copy()复制子剪贴板来解决它。我不知道任何类似的字符串复制操作。
举例来说,
$是一种常用的方法来创建子字符串的副本 b$ b
包裹主要
进口(
fmt
不安全
)
类型字符串结构{
str *字节
len int
}
func main(){
str:= abc
substr:= string([] byte(str [1:]))
fmt.Println(str,substr)
fmt.Println(*(* String)(unsafe .Pointer(& str)),*(* String)(unsafe.Pointer(& substr)))
}
$ b $输出:
abc bc
{0x4c0640 3} {0xc21000c940 2}
When taking a substring of a string in Go, no new memory is allocated. Instead, the underlying representation of the substring contains a Data pointer that is an offset of the original string's Data pointer.
This means that if I have a large string and wish to keep track of a small substring, the garbage collector will be unable to free any of the large string until I release all references to the shorter substring.
Slices have a similar problem, but you can get around it by making a copy of the subslice using copy(). I am unaware of any similar copy operation for strings. What is the idiomatic and fastest way to make a "copy" of a substring?
For example,
package main
import (
"fmt"
"unsafe"
)
type String struct {
str *byte
len int
}
func main() {
str := "abc"
substr := string([]byte(str[1:]))
fmt.Println(str, substr)
fmt.Println(*(*String)(unsafe.Pointer(&str)), *(*String)(unsafe.Pointer(&substr)))
}
Output:
abc bc
{0x4c0640 3} {0xc21000c940 2}
这篇关于子串和Go垃圾收集器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!