نوع rune في Go اسم مستعار لـ int32.
ونظرًا لأن نوع rune يستند إلى هذا النوع int32، فإنه يحمل قيمة عددية صحيحة ذات إشارة بسعة 32 بت.
لكن على خلاف النوع int32، تمثّل القيمة العددية المخزّنة في نوع rune محرف يونيكود واحدًا.
يونيكود مجموعة شاملة لـ ASCII، ويمثّل المحارف عبر إعطاء رقم فريد لكل محرف. ويُسمى هذا الرقم الفريد نقطة ترميز يونيكود. يهدف يونيكود إلى تمثيل جميع محارف العالم، بما فيها مختلف الأبجديات والأرقام والرموز وحتى الرموز التعبيرية، على هيئة نقاط ترميز يونيكود.
في Go، يمثّل نوع rune نقطة ترميز يونيكود واحدة.
يعرض الجدول التالي أمثلة على محارف يونيكود مع نقاط ترميزها وقيمها العشرية:
| محرف يونيكود | نقطة ترميز يونيكود | القيمة العشرية |
|---|---|---|
| 0 | U+0030 |
48 |
| A | U+0041 |
65 |
| a | U+0061 |
97 |
| ¿ | U+00BF |
191 |
| π | U+03C0 |
960 |
| 🧠 | U+1F9E0 |
129504 |
UTF-8 هو ترميز محارف متغيّر العرض، يُستخدم لترميز كل نقطة ترميز يونيكود على هيئة 1 أو 2 أو 3 أو 4 بايتات.
ولأن نقطة ترميز يونيكود يمكن ترميزها في 4 بايتات كحد أقصى، يحتاج نوع rune إلى القدرة على تخزين ما يصل إلى 4 بايتات من البيانات.
ولهذا فإن نوع rune اسم مستعار لـ int32، لأن النوع int32 قادر على تخزين ما يصل إلى 4 بايتات من البيانات.
تُرمَّز ملفات الكود المصدري في Go باستخدام UTF-8.
rune
تُعرَّف المتغيرات من نوع rune بوضع محرف بين علامتَي اقتباس مفردتين:
myRune := '¿'
ولأن rune مجرد اسم مستعار لـ int32، فإن طباعة نوع rune ستُنتج int32:
myRune := '¿'
fmt.Printf("myRune type: %T\n", myRune)
// Output: myRune type: int32
وبالمثل، فإن طباعة قيمة rune ستُنتج قيمتها العددية الصحيحة (العشرية):
myRune := '¿'
fmt.Printf("myRune value: %v\n", myRune)
// Output: myRune value: 191
لطباعة محرف يونيكود الذي يمثّله الـ rune، استخدم صيغة التنسيق %c:
myRune := '¿'
fmt.Printf("myRune Unicode character: %c\n", myRune)
// Output: myRune Unicode character: ¿
ولطباعة نقطة ترميز يونيكود التي يمثّلها الـ rune، استخدم صيغة التنسيق %U:
myRune := '¿'
fmt.Printf("myRune Unicode code point: %U\n", myRune)
// Output: myRune Unicode code point: U+00BF
rune والسلاسل النصيةتُرمَّز السلاسل النصية في Go باستخدام UTF-8، ما يعني أنها تحتوي على محارف يونيكود. وتُخزَّن المحارف في السلاسل النصية وتُرمَّز على هيئة 1 أو 2 أو 3 أو 4 بايتات، حسب محرف يونيكود الذي تمثّله.
في Go، تُستخدم الشرائح لتمثيل المتتاليات، ويمكن المرور على هذه الشرائح باستخدام range.
وعندما نمرّ على سلسلة نصية، يحوّلها Go إلى متتالية من أنواع rune، كل منها بحجم 4 بايتات (تذكّر أن نوع rune اسم مستعار لـ int32!)
وعلى الرغم من أن السلسلة النصية مجرد شريحة من البايتات، فإن الكلمة المفتاحية range تمرّ على أنواع rune في السلسلة النصية، لا على بايتاتها.
في هذا المثال، يمثّل المتغير index فهرس البداية لتسلسل بايتات الـ rune الحالي، ويمثّل المتغير char الـ rune الحالي:
myString := "❗hello"
for index, char := range myString {
fmt.Printf("Index: %d\tCharacter: %c\t\tCode Point: %U\n", index, char, char)
}
// Output:
// Index: 0 Character: ❗ Code Point: U+2757
// Index: 3 Character: h Code Point: U+0068
// Index: 4 Character: e Code Point: U+0065
// Index: 5 Character: l Code Point: U+006C
// Index: 6 Character: l Code Point: U+006C
// Index: 7 Character: o Code Point: U+006F
ولأن أنواع rune يمكن تخزينها في 1 أو 2 أو 3 أو 4 بايتات، فقد لا يساوي طول السلسلة النصية دائمًا عدد المحارف فيها.
استخدم الدالة المدمجة len للحصول على طول السلسلة النصية بالبايتات، والدالة utf8.RuneCountInString للحصول على عدد أنواع rune في السلسلة النصية:
import "unicode/utf8"
myString := "❗hello"
stringLength := len(myString)
numberOfRunes := utf8.RuneCountInString(myString)
fmt.Printf("myString - Length: %d - Runes: %d\n", stringLength, numberOfRunes)
// Output: myString - Length: 8 - Runes: 6
أُوكلت إليك مهمة إنشاء مكتبة للسجلات تساعدك في إدارة سجلات مؤسستك. ستتيح هذه المكتبة للمستخدمين تحديد التطبيق الذي أصدر سجلًا معينًا، وإصلاح السجلات التالفة، ومعرفة ما إذا كان سطر السجل المعين يقع ضمن حد معين من الأحرف.
تأتي السجلات من تطبيقات متعددة، ويستخدم كل منها تنسيق سجلات خاصًا به. ويجب تحديد التطبيق الذي أصدر السجل قبل تخزينه في نظام لتجميع السجلات.
نفّذ الدالة Application التي تأخذ سطر السجل وتُرجع التطبيق الذي أصدر هذا السطر.
لتحديد التطبيق الذي أصدر سطر سجل معين، ابحث في سطر السجل عن حرف محدد وفق ما يوضّحه الجدول التالي:
| التطبيق | الحرف | نقطة ترميز Unicode |
|---|---|---|
recommendation |
❗ | U+2757 |
search |
🔍 | U+1F50D |
weather |
☀ | U+2600 |
إذا لم يحتوي سطر السجل على أي من الأحرف الواردة في الجدول أعلاه، فأرجع default إلى المستدعي.
وإذا احتوى سطر السجل على أكثر من حرف من الجدول أعلاه، فأرجع التطبيق المقابل لأول حرف يصادفه السطر من اليسار إلى اليمين.
Application("❗ recommended search product 🔍")
// => recommendation
بسبب وجود bug نادر لكنه مستمر في البنية التحتية للتسجيل، يمكن أن تتلف أحرف معينة في السجلات. وبعد أن أمضيت وقتًا في تحديد الأحرف التالفة وقيمتها الأصلية، قررت تحديث مكتبة السجلات للمساعدة في إصلاح السجلات التالفة.
نفّذ الدالة Replace التي تأخذ سطر السجل، وحرفًا تالفًا، والقيمة الأصلية، وتُرجع سطر سجل معدّلًا استُبدلت فيه كل حالات ورود الحرف التالف بالقيمة الأصلية.
log := "please replace '👎' with '👍'"
Replace(log, '👎', '👍')
// => please replace '👍' with '👍'"
الأنظمة المسؤولة عن عرض السجلات لها حد أقصى لعدد الأحرف التي يمكن عرضها في سطر السجل الواحد. ولذلك، يطلب المستخدمون أن تضم هذه المكتبة دالة مساعدة تحدّد ما إذا كان سطر السجل يقع ضمن حد معين من الأحرف أم لا.
نفّذ الدالة WithinLimit التي تأخذ سطر السجل وحدّ الأحرف وتُرجع ما إذا كان سطر السجل يقع ضمن حد الأحرف أم لا.
WithinLimit("hello❗", 6)
// => true
سجّل في Exercism لتتعلّم وتتقن Go عبر 34 مفهومًا165 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.