طريقة واحدة لتسمية قيمة
في Zero، تُعطي قيمة اسمًا بـ let:
let answer = 42
هذه هي الصياغة كاملة. لا var، ولا const، ولا auto. كلمة ربط واحدة تُبقي اللغة صغيرة — يتعلّمها الوكلاء والبشر مرة واحدة ويُطبّقونها في كل مكان.
let تُقدّم ربطًا محليًا في النطاق الحالي. بعد هذا السطر، يُشير answer إلى 42 حتى نهاية الكتلة المحيطة.
استنتاج النوع
يستنتج المترجم النوع من الجانب الأيمن (يمين علامة المساواة). القيمة الحرفية 42 نوعها i32 افتراضيًا، لذا answer من النوع i32. القيمة الحرفية "hello" نصّ، لذا:
let greeting = "hello"
يربط greeting بقيمة نصّية. إن استدعيت دالة تُعيد Pair<i32, u8>، فالربط يأخذ النوع Pair<i32, u8>:
let pair = makePair(40, 2_u8)
لست مضطرًا لكتابة النوع على كل ربط، وهذا يُبقي الشيفرة سهلة القراءة.
تعليقات النوع الصريحة
عندما تريد توثيق النوع — أو فرض نوع معيّن حين قد يختار الاستنتاج نوعًا مختلفًا — اكتب النوع بعد النقطتين:
let count: u8 = 10
let pair: Pair<i32, u8> = makePair(40, 2_u8)
التعليقات أيضًا تلميح للمترجم عندما يمكن أن تكون القيمة الحرفية من أنواع متعدّدة. القيمة الحرفية 10 قد تكون i32 أو i64 أو u8 وهكذا؛ والتعليق يُثبّتها.
سترى أيضًا لواحق نوع على القيم الحرفية بديلًا عن تعليق الربط:
let small = 10_u8 // u8 من لاحقة القيمة الحرفية
let big = 10_i64 // i64 من لاحقة القيمة الحرفية
كلا الشكلين صالح؛ اختر ما يجعل النيّة أوضح في موقع الاستدعاء.
الروابط في العمل
مثال متكامل يستخدم النوع المُستنتَج والصريح — اضغط Run لتجربته:
point معلَّق صراحة لأن الجانب الأيمن قيمة حرفية لبنية. أمّا total فمُستنتَج — sum معلَنة بأنها تُعيد i32، لذا الربط i32 أيضًا.
النطاق والحجب
ربط let صالح من السطر الذي يُعلنه حتى نهاية الكتلة المحيطة. الكتل المُتداخلة تُنشئ نطاقات جديدة:
pub fun main(world: World) -> Void raises {
let value = 1
if true {
let value = 2 // يحجب القيمة الخارجية داخل هذه الكتلة
// هنا، value == 2
}
// بعد الخروج من if، value == 1 مرة أخرى
}
الـ value الداخلي لا يُعدّل الخارجي — هو ربط منفصل ينتهي نطاقه عند القوس المغلق لكتلة if. هذا هو النموذج نفسه في Rust ولغات عائلة ML. يشيع هذا الاستخدام عندما تريد تحويل قيمة عبر سلسلة من الخطوات دون اختراع أسماء جديدة لكل ناتج وسيط.
ما لا تفعله let
بعض الأشياء التي قد تتوقّعها من لغات أخرى لا تتضمّنها let عمدًا:
- تعريفات النوع فقط. لا توجد صيغة
let x: i32;تُقدّم ربطًا غير مُهيَّأ. يجب أن يكون للربط قيمة عند نقطة إعلانه. - تفكيك الأنماط (حتى الآن). بعض اللغات تسمح بكتابة
let (a, b) = pair. Zero صغيرة بحكم التصميم وتُركّز حاليًا على روابط الاسم البسيطة — راجع التوثيق الحالي لمعرفة ما إذا كان التفكيك متوفّرًا. - كلمات متعدّدة لأعمار مختلفة. لا
staticمنفصلة، ولاconst، ولاlet mut، ولا متغيّرات على مستوى الكتلة مقابل مستوى الدالة. كلمة واحدة.
إذا كانت خلفيتك JavaScript، فالأقرب هو const — اسم مرتبط بقيمة لبقية الكتلة، مع حجب في النطاقات الداخلية. إذا كانت خلفيتك Rust، فإن let هنا تلعب الدور نفسه الذي تلعبه let في Rust دون كلمة mut الصريحة.
نمط: بناء قيمة خطوة بخطوة
تتألّق الروابط عندما تريد كتابة حساب كسلسلة من الخطوات الوسيطة المُسمَّاة. هذا جيّد للبشر القارئين وللوكلاء الذين يستدلّون محليًا على كل سطر:
كل سطر يُقدّم حقيقة جديدة لتعمل بقية الدالة بناءً عليها. لا يزال المترجم يُنتج شيفرة محكمة — لا تكلفة في زمن التشغيل لتسمية القيم الوسيطة.
التالي: الأنواع الأوّلية
let لا تعني الكثير دون شيء لربطه. التوثيق التالي يمرّ بـ الأنواع الأوّلية في Zero — عروض الأعداد الصحيحة، والكسور العشرية، والنصوص، والنوعَين Void وBool اللذين ستراهما أكثر شيء.
الأسئلة الشائعة
كيف تُعلن متغيّرًا في Zero؟
استخدم let. الصيغة let name = value للنوع المُستنتَج، أو let name: Type = value لكتابة النوع صراحة. مثلًا: let answer = 42 أو let answer: i32 = 42. كلاهما يربط الاسم answer بالقيمة 42 في النطاق الحالي.
هل تستنتج Zero الأنواع لروابط let؟
نعم. إذا كتبت let total = sum(point) وكانت sum تُعيد i32، فإن نوع الربط يُستنتَج كـ i32. تستطيع مع ذلك التعليق صراحة عندما تريد توثيق النوع أو فرض نوع محدّد — مثلًا let count: u8 = 10.
هل روابط let في Zero قابلة للتعديل؟
let المجرّدة تُقدّم ربطًا محليًا للاستخدام داخل نطاقه. قصة قابلية التعديل في Zero قبل الإصدار 1.0 لا تزال تتطوّر — تُؤكّد اللغة على التأثيرات الصريحة والذاكرة المتوقّعة، لذا أي شيء يُعدّل الحالة عبر ربط يجب أن يُظهر ذلك. راجع توثيق Zero الحالي لمعرفة الصياغة الدقيقة لقابلية التعديل في إصدار سلسلة أدواتك.
ما الفرق بين let وconst في Zero؟
تستخدم Zero let للروابط المحلية العادية داخل أجسام الدوال. لا تكشف عن كلمات مفتاحية متعدّدة للربط مثل let/const/var في JavaScript — إبقاء المساحة السطحية صغيرة خيار تصميمي متعمّد. الثوابت في زمن الترجمة تُعبَّر عنها عادةً عبر نظام الأنواع أو الإعلانات على المستوى الأعلى، لا عبر كلمة مفتاحية منفصلة.
هل يمكن إعادة الإعلان عن ربط let في Zero؟
الروابط تعيش داخل نطاقها المُحيط. let جديد بالاسم نفسه في نطاق مُتداخل هو ربط منفصل يحجب الخارجي لمدّة النطاق الداخلي — الربط الخارجي لا يتأثّر بمجرّد انتهاء النطاق الداخلي. هذا هو النموذج نفسه الذي تستخدمه Rust ولغات عائلة ML.