2013-06-04 39 views
6

当在Go中取一个字符串的子字符串时,不会分配新的内存。相反,子字符串的底层表示包含一个数据指针,它是原始字符串的数据指针的偏移量。子字符串和Go垃圾回收器

这意味着,如果我有一个大的字符串,并希望保留一小串的轨迹,垃圾收集器将无法释放任何大串的,直到我释放较短字符串的所有引用。

切片有类似的问题,但你可以通过使用copy()复制子切片来解决它。我不知道任何类似的字符串复制操作。什么是创建子字符串“复制”的惯用和最快的方法?

+1

这是一种围棋的缺点。为此,应该可以使用make(string,foo [x:y])。 – fuz

回答

1

例如,

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))) 
} 

输出:

abc bc 
{0x4c0640 3} {0xc21000c940 2} 
+1

此解决方案是否不会生成子字符串的两个副本?一个用于转换为[]字节,另一个用于转换回字符串? – Beevik

+1

是的,不幸的。但是,字节片是暂时的。 – peterSO