Go 中是否有与 Java 的 String intern 函数等效的函数?

Mal*_*olm 3 java string go

Go 中是否有与 Java 的 String intern 函数等效的函数?

我正在解析大量具有重复模式(标签)的文本输入。我希望提高内存效率,并为每个标签存储指向单个字符串的指针,而不是为每次出现的标签存储多个字符串。

Ste*_*erg 5

据我所知,不存在这样的功能。但是,您可以使用地图轻松制作自己的地图。字符串类型本身是一个 uintptr 和一个长度。因此,从另一个字符串分配的字符串只占用两个单词。因此,您所需要做的就是确保不存在两个具有冗余内容的字符串。

这是我的意思的一个例子。

type Interner map[string]string

func NewInterner() Interner {
    return Interner(make(map[string]string))
}

func (m Interner) Intern(s string) string {
    if ret, ok := m[s]; ok {
        return ret
    }

    m[s] = s
    return s
}
Run Code Online (Sandbox Code Playgroud)

每当您执行以下操作时,此代码都会删除冗余字符串:

str = interner.Intern(str)
Run Code Online (Sandbox Code Playgroud)

编辑:正如 jnml 提到的,我的答案可以根据给出的字符串固定内存。有两种方法可以解决这个问题。这两个都应该插入m[s] = s到我之前的示例中。第一个将字符串复制两次,第二个使用不安全。两者都不理想。

双副本:

b := []byte(s)
s = string(b)
Run Code Online (Sandbox Code Playgroud)

不安全(使用风险自负。适用于当前版本的 gc 编译器):

b := []byte(s)
s = *(*string)(unsafe.Pointer(&b))
Run Code Online (Sandbox Code Playgroud)