Go / الأساسي: القيم وعقود البرامج / الدرس 2
الأنواع والقيم الصفرية والتحويلات
اختر التمثيلات عمدا واشرح محتوى المتغير قبل تقديم مهيئ صريح.
في هذه الصفحة
أهداف الدرس
- تحديد القيم الصفرية للأنواع العددية والمنطقية والنصية والحاملة للمراجع.
- تمييز الأنواع المسماة من الأسماء البديلة والتحويلات الصريحة.
- فصل طول البايتات والمحارف الرونية والنص المعروض.
المتغير المصرح به يبدأ بقيمة محددة
دون مهيئ صريح تمنح Go المتغير القيمة الصفرية لنوعه: صفر عددي أو false أو نص فارغ أو nil للمؤشرات والشرائح والخرائط والقنوات والدوال والواجهات. وتحتوي المصفوفات والبنى عناصر وحقولا صفرية على نحو متكرر. يجعل ذلك البداية متوقعة لكنه لا يعني دعم كل عملية.
يمكن الإلحاق بشريحة nil، لكن إسناد عنصر في خريطة nil يسبب هلعا. ولا يمكن فك مؤشر nil. ميز الحالة الفارغة المفيدة من مورد مكتمل التهيئة. تجعل الواجهة الجيدة قيمتها الصفرية مفيدة أو توثق بوضوح التهيئة اللازمة.
فحص القيم الصفرية دون فك nil
يطبع المثال الأول القيم ومقارنات nil دون عملية غير صالحة. يقتبس %q النص الفارغ فيظهر بدلا من أن يبدو إخراجا مفقودا. طول شريحة nil صفر رغم عدم إنشاء مصفوفة خلفية صراحة. تجيب صفريتها وطولها عن سؤالين مختلفين.
لا تستخدم التمثيل المطبوع اختبار مساواة مستقلا عن النوع. قد يكون طول شريحة nil وشريحة فارغة مخصصة صفرا مع اختلاف المقارنة بـnil وبعض سلوك الترميز. قرر هل يخص التمييز عقد التطبيق بدلا من افتراض تطابق الغياب والفراغ دائما.
package main
import "fmt"
func main() {
var count int
var ready bool
var label string
var values []int
var pointer *int
fmt.Printf("%d %t %q %d %t %t\n", count, ready, label, len(values), values == nil, pointer == nil)
}
0 false "" 0 true true
يفحص البرنامج قيم nil بأمان ويظهر النص الفارغ بعلامتي اقتباس.
التمثيل يحدد الحساب
لـint حجم يعتمد على التنفيذ، عادة 32 أو64 بتا؛ استخدم عرضا صريحا عندما تتطلب الواجهة مداه فعلا. لا تخلط Go أنواع المتغيرات العددية المختلفة ضمنيا. يطلب التحويل تغيير تمثيل محددا وقد يفقد معلومات. افحص حدود التطبيق قبل تضييق البيانات الخارجية.
تحذف القسمة الصحيحة الكسر باتجاه الصفر. لا يستعيد تحويل الخارج لاحقا الكسر؛ حوّل أحد المعاملين قبل القسمة للحساب العائم. الحساب العائم تقريبي، ولذلك يعد تنسيق منزلتين سياسة عرض لا برهانا على تمثيل كل كسر عشري ثنائيا بدقة.
التحويل عند العملية المحتاجة إليه
يحسب البرنامج التالي حصتين من القيم الصحيحة الصغيرة نفسها. تنتج القسمة الأولى ثلاثة قبل التحويل. تحول الثانية total إلى float64 فتقسم في المجال العائم. النتيجتان محددتان بغض النظر عن عرض int لأن القيم والنتائج الوسيطة صغيرة.
تمنح الأنواع المعرفة أسماء مجال لتمثيل، مثل type Celsius float64. يظل نوعان معرفان مختلفين ولو تطابق نوعهما الأساسي، فيمنع ذلك خلطا عرضيا. أما الاسم البديل فيسمي نوعا مطابقا موجودا. لا يفرض الاسم ولا التحويل وحدات فيزيائية أو حدود عمل تلقائيا.
package main
import "fmt"
func main() {
total, people := 7, 2
truncated := float64(total / people)
share := float64(total) / float64(people)
fmt.Printf("%.2f %.2f\n", truncated, share)
}
3.00 3.50
فقدت النتيجة الأولى كسرها بالفعل؛ وتحفظ الثانية النصف.
النص متتالية بايتات ثابتة
نص Go متتالية بايتات ثابتة وقد يحتوي بايتات عشوائية لا UTF-8 صالحا فقط. تبلغ len عدد البايتات. وتمثل rune اسما بديلا لـint32 وتستخدم اصطلاحا لنقطة Unicode. يفك range على النص UTF-8 وينتج فهارس بايتات وقيما رونية؛ وللتسلسلات المعيبة تفسير فك موثق.
قد يتكون المحرف المرئي من عدة نقاط ترميز، فلا يساوي عدد الرونات دائما عدد المحارف لدى المستخدم. اختر معالجة البايتات للبروتوكولات وعمليات Unicode لمتطلبات النص. ولا يجعل ثبات النص إسناد متغير نصي مشترك آمنا دون مزامنة؛ فتلك مسألة منفصلة.
الأخطاء الشائعة وإصلاحها
يحمل متغير عائم خارجا مبتورا.
- لماذا يحدث؟
- حدثت قسمة صحيحة قبل التحويل.
- كيف تصلحه؟
- حوّل أحد المعاملين قبل القسمة.
- كيف تتجنب تكراره؟
- دوّن أنواع التعابير الوسيطة عند مراجعة الحساب.
تسبب الكتابة لخريطة nil هلعا.
- لماذا يحدث؟
- لا تملك الخريطة الصفرية تخزينا مهيأ للكتابة.
- كيف تصلحه؟
- هيئها باستخدام make أو تعبير خريطة.
- كيف تتجنب تكراره؟
- وثق القيم الصفرية القابلة للاستخدام مباشرة.
يرفض حد النص محارف أو يبترها على نحو مفاجئ.
- لماذا يحدث؟
- اختلط عدد البايتات بالنقاط أو عرض العرض.
- كيف تصلحه؟
- حدد الوحدة المطلوبة وعملية تناسبها.
- كيف تتجنب تكراره؟
- اختبر غير ASCII والمحارف المركبة.
اختبر فهمك
1. اشرح الفرق بين var s []int وs := make([]int, 0) والعمليات الآمنة على الفراغ.
اعرض الحل المشروح
طول كلتيهما صفر ولا ينفذ range أية دورة. تساوي الأولى nil ولا تساويها الثانية. يستطيع append توسيعهما ويجب حفظ الشريحة المعادة. الفهرس صفر غير صالح لكليهما لأن الطول، لا nil ولا السعة، يضبط الفهرسة. ينبغي أن تحدد الواجهة هل تعني nil الغياب.
2. يقبل بروتوكول عددا عشريا من صفر إلى مئة. لماذا يفصل التحليل عن التحويل لنوع أصغر؟
اعرض الحل المشروح
حلل بعملية تبلغ أخطاء الصياغة والمدى ثم افحص مجال التطبيق قبل التضييق. لا يعد التحويل وحده فحص رفض وقد يفقد البتات العليا أو يغير التمثيل. احفظ الحالة الصالحة السابقة حتى نجاح كل الفحوص. اختبر السالب و100 و101 وقيمة تتجاوز مدى المحلل.
أهم ما تعلمته
- القيم الصفرية محددة لكن للعمليات شروطا مسبقة.
- تغير التحويلات التمثيل عند موضع معين.
- طول البايتات ونقاط الترميز والنص المرئي وحدات مختلفة.