3

GoでJavaのStringインターン関数に相当するものはありますか?

繰り返しパターン (タグ) を持つ多くのテキスト入力を解析しています。私はそれについてメモリ効率を高め、タグの出現ごとに複数の文字列ではなく、タグごとに単一の文字列へのポインターを格納したいと考えています。

4

2 に答える 2

4

私が知っているそのような機能は存在しません。ただし、マップを使用して非常に簡単に独自のものを作成できます。文字列型自体は uintptr と長さです。そのため、別の文字列から割り当てられた文字列は 2 語しか使用しません。したがって、冗長な内容を持つ 2 つの文字列がないことを確認するだけで済みます。

これが私の言いたいことの例です。

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)

EDIT:jnmlが述べたように、私の答えは、与えられた文字列に応じてメモリを固定する可能性があります。この問題を解決するには 2 つの方法があります。これらは両方ともm[s] = s、前の例の前に挿入する必要があります。1 つ目は文字列を 2 回コピーし、2 つ目は unsafe を使用します。どちらも理想的ではありません。

ダブルコピー:

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

安全でない (自己責任で使用してください。現在のバージョンの gc コンパイラで動作します):

b := []byte(s)
s = *(*string)(unsafe.Pointer(&b))
于 2012-10-22T18:47:44.813 に答える
1

たとえば、PoolGoPoolがあなたのニーズを満たすかもしれないと思います。そのコードは、Stephen のソリューションが無視する 1 つの問題を解決します。Go では、文字列値はより大きな文字列のスライスである場合があります。シナリオは問題にならない場所であり、シナリオはそれがショー ストッパーである場所です。リンクされた機能は、安全側にいるように努めます。

于 2012-10-22T20:00:38.570 に答える