GoでJavaのStringインターン関数に相当するものはありますか?
繰り返しパターン (タグ) を持つ多くのテキスト入力を解析しています。私はそれについてメモリ効率を高め、タグの出現ごとに複数の文字列ではなく、タグごとに単一の文字列へのポインターを格納したいと考えています。
私が知っているそのような機能は存在しません。ただし、マップを使用して非常に簡単に独自のものを作成できます。文字列型自体は 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))