在Go中是否有与Java的String intern函数相同的功能?

时间:2012-10-22 18:30:44

标签: java string go

Go中是否存在与Java的String intern函数等效的内容?

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

2 个答案:

答案 0 :(得分:4)

我知道没有这样的功能。但是,您可以使用地图轻松制作自己的地图。字符串类型本身是一个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
}

只要执行以下操作,此代码就会对冗余字符串进行重复数据删除:

str = interner.Intern(str)

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

双重复制:

b := []byte(s)
s = string(b)

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

b := []byte(s)
s = *(*string)(unsafe.Pointer(&b))

答案 1 :(得分:1)

我认为例如PoolGoPool可能会满足您的需求。该代码解决了斯蒂芬解决方案忽略的一件事。在Go中,字符串值可以是更大字符串的片段。场景是无关紧要的,场景是一个显示阻止的地方。链接的功能试图安全起见。