أثناء تشغيل برامج Go، لا تتشارك بعض النصوص المتساوية أحياناً كتل ذاكرة البايتات الأساسية، حتى وإن أمكنها تشارك كتلة ذاكرة بايتات مشتركة واحدة.
تُسمّى عملية جعلهما تتشاركان كتلة ذاكرة بايتات مشتركة واحدة توحيد النصوص (string canonicalization). هناك عدة طرق في Go لتنفيذ توحيد النصوص.
الطريقة 1: توحيد نصين عند اكتشاف تساويهما
المنطق والتنفيذ بسيطان:
if str1 == str2 {
str1 = str2 // التخلي عن كتلة ذاكرة البايتات الأساسية لـ str2
}
إليك تنفيذاً ركيكاً لتوحيد النصوص في شريحة:
func CanonicalizeStrings(ss []string) {
type S struct {
str string
index int
}
var temp = make([]S, len(ss))
for i := range temp {
temp[i] = S {
str: ss[i],
index: i,
}
}
for i := 0; i < len(temp); {
var k = i+1
for j := k; j < len(temp); j++ {
if temp[j].str == temp[i].str {
temp[j].str = temp[i].str
temp[k], temp[j] = temp[j], temp[k]
k++
}
}
i = k
}
for i := range temp {
ss[temp[i].index] = temp[i].str
}
}
هذه الطريقة أكثر أداءً من الطريقة التالية في الحالة المحددة (توحيد كل النصوص في شريحة).
الطريقة 2: استخدام unique.Handle المُقدَّمة في Go 1.23
قدّمت Go 1.23 unique.Handle، وهي طريقة ملائمة لتوحيد النصوص.
import "unique"
func CanonicalizeString(s string) string {
return unique.Make(s).Value()
}
func CanonicalizeStrings(ss []string) {
for i, s := range ss {
ss[i] = CanonicalizeString(s)
}
}
هذه الطريقة أكثر مرونة. ما عليك سوى تطبيق دالة CanonicalizeString أعلاه على كل نص يُستخدم أثناء التشغيل، وعندها ستتشارك كل النصوص المتساوية كتل ذاكرة البايتات الأساسية نفسها.
ملاحظة: طريقة unique.Make ليست مناسبة دائماً لكل الحالات. ستخصص دالة unique.Make كتلة ذاكرة بايتات داعمة لكل نص مختلف. لذا إذا تشاركت بعض النصوص غير المتساوية المراد توحيدها كتلة ذاكرة البايتات الداعمة نفسها، فستخصص دالة unique.Make كتلة ذاكرة تسلسل بايتات داعمة جديدة لكل من هذه النصوص. وهذا في الواقع يخصص ذاكرة أكثر (من استخدام كتلة ذاكرة واحدة).