
مرحبا يا هبر!
منذ فترة طويلة ، كنت أكتب إطار لعبتي - مثل مشروع الحيوانات الأليفة للروح. وحيث إن الروح تحتاج إلى اختيار شيء تحبه (وفي هذه الحالة ، ما تحب أن تكتب عليه) ، فإن خياري وقع على نيم. في هذه المقالة أريد أن أتحدث بالتحديد عن nim ، وعن ميزاته وإيجابياته وسلبياته ، وموضوع gamedev يحدد فقط سياق تجربتي - ما هي المهام التي حلتها ، وما الصعوبات التي نشأت.
ذات مرة ، عندما كان العشب أكثر خضرة ونظافة السماء ، التقيت نيم. لا ، ليس هكذا. ذات مرة ، كنت أرغب في تطوير ألعاب لكتابة أروع لعباتي - أعتقد أن الكثير منهم مروا بهذا. في تلك الأيام ، كانت Unity و Unreal Engine بدأت للتو في الظهور على السمع ، ومثل ، لم تكن حرة بعد. لم أستخدمها ، ليس بسبب الجشع ، ولكن بسبب الرغبة في كتابة كل شيء بنفسي ، لإنشاء عالم ألعاب بالكامل من نقطة الصفر ، من الأول صفر بايت. نعم ، لفترة طويلة ، نعم ، إنه أمر صعب ، لكن العملية نفسها تجلب السرور - لكن ماذا هناك حاجة للسعادة؟
بعد أن كنت مسلحًا مع Straustrup و Qt ، شربت القرف من أجل الخير ، لأنني أولاً ، لم أكن أحد الأشخاص العشرة في العالم الذين يعرفون C ++ جيدًا ، وثانياً ، وضعت الإيجابيات عصيًا في عجلاتي. لا أرى أي سبب لتكرار ما كتبه لي بالفعل:
كيف وجدت أفضل لغة برمجة في العالم. الجزء 1
كيف وجدت أفضل لغة برمجة في العالم. الجزء 2
كيف وجدت أفضل لغة برمجة في العالم. يو الجزء (2.72)
هذا صخب مجنون عندما تكتب الشفرة بحرية ، دون تفكير تقريبًا ، دون انتظار التخلص من النواة قبل كل إطلاق ، وعند إضافة الميزات مباشرة أمام أعيننا ، يمكننا الآن القيام بذلك ، والآن هكذا ، أخبرني من فضلك ، ما الفرق الذي يحدثه هذا الأمر بالنسبة لي ليس لدي قوالب إذا لم أفتقدها؟ الإنتاجية هي الهدف الرئيسي للمبرمج الذي يفعل الأشياء ، والمهمة الوحيدة للأداة التي يستخدمها.
عند العمل مع C ++ ، كنت أفكر باستمرار حول كيفية كتابة ما أريد ، وليس ما أكتب لي. لذلك تحولت إلى نيم. انتهت القصة ، واسمحوا لي أن أشارككم تجربتي بعد عدة سنوات.
معلومات عامة لأولئك الذين ليسوا في معرفة
- مترجم مفتوح المصدر (MIT) ، تم تطويره من قبل المتحمسين. مبدع اللغة هو أندرياس رومب (عراق). المطور الثاني هو دومينيك بيتشيتا (dom96) ، الذي كتب كتاب نيم في العمل . أيضًا ، منذ بعض الوقت بدأت Status في رعاية تطوير اللغة ، لذلك حصل nim على مطورين متفرغين. بالإضافة إليهم ، بالطبع ، سوف يساهم أشخاص آخرون.
- تم إصدار الإصدار 1.0 مؤخرًا ، مما يعني أن اللغة مستقرة وأن "التغييرات العاجلة" لم تعد متوقعة. إذا لم تكن ترغب في استخدام الإصدار غير المستقر من قبل ، لأن التحديثات قد تؤدي إلى انقطاع التطبيق ، فقد حان الوقت لتجربة تطبيق nim في مشاريعك.
- يقوم Nim بتجميع (أو تبديل) في C أو C ++ (والتي يتم تجميعها بشكل أكبر في الكود الأصلي) أو JS (مع بعض القيود). وفقًا لذلك ، بمساعدة FFI ، تتوفر لك كل المكتبات الحالية لـ C و C ++. إذا لم يكن هناك حزمة ضرورية على نيم - ابحث عن ليالي أو إيجابيات.
- أقرب اللغات هي الثعبان (عن طريق بناء الجملة ، للوهلة الأولى) و D (حسب الوظيفة) - IMHO
الوثائق
هذا سيء بالفعل. المشاكل:
- الوثائق مبعثرة على مصادر مختلفة
- الوثائق
القرف لا يصف بالكامل جميع ميزات اللغة - الوثائق في بعض الأحيان موجزة جدا.
على سبيل المثال: إذا كنت تريد كتابة تطبيقات متعددة الخيوط ، فهناك الكثير من النوى ، ولكن لا يوجد مكان تذهب إليه.
هنا قسم الوثائق الرسمية على الجداول . لا ، كما ترى ، تعتبر --threads:on
جزءًا كبيرًا منفصلاً من اللغة ، وهي ميزة تحتاج حتى إلى تضمينها مع - --threads:on
flag عند التحويل البرمجي. هناك ، كومة الذاكرة المؤقتة المشتركة أو مؤشر ترابط محلي اعتمادًا على أداة تجميع مجمعي البيانات المهملة ، وجميع أنواع الذاكرة المشتركة والأقفال ، وسلامة مؤشر الترابط ، والوحدات النمطية الخاصة المشتركة ، والجحيم تعرف ماذا. كيف عرفت كل هذا؟ هذا صحيح ، من الكتاب الذي لا يزال قيد التنفيذ ، والمنتدى ، وتكدس المكدس ، والتلفزيون ومن الجار ، بشكل عام ، من أي مكان ، ولكن ليس من الوثائق الرسمية.
أو هناك ما يسمى. "لا تدوين" - يعمل بشكل جيد جدًا عند استخدام القوالب ، وما إلى ذلك ، بشكل عام حيثما تحتاج إلى تمرير رد اتصال أو مجرد مجموعة من التعليمات البرمجية. أين يمكنني أن أقرأ عن ذلك؟ نعم ، في دليل الميزات التجريبية .
توافق على أن جمع المعلومات حول مختلف المصادر غير الصحيحة لا يزال من دواعي سروري. إذا كتبت في نيم ، عليك أن تفعل ذلك.
في المنتدى وفي قضايا github ، كانت هناك اقتراحات لتحسين الوثائق ، لكن الأمور لم تتحرك إلى الأمام. يبدو لي أن هناك نوعًا من الأيدي القاسية مفقودة ، والتي ستقول "كل شيء ، المجتمع ، يأخذ المجارف ويذهب ليجعل هذه المجموعة من ... أجزاء مبعثرة من النص".
لحسن الحظ ، لقد ضربت بلدي ، لذلك أقدم لكم قائمة بطل نيم
الوثائق
- البرنامج التعليمي 1 ، البرنامج التعليمي 2 - ابدأ معهم
- نيم في العمل هو كتاب توضيحي يشرح الكثير من جوانب اللغة ، وأحيانًا يكون أفضل منه. توثيق
- دليل نيم - في الواقع ، دليل - يتم وصف كل شيء تقريبًا ، لكن لا
- دليل تجريبي نيم - لماذا لا تستمر في الواقع الوثائق على صفحة منفصلة؟
- الفهرس - يتم جمع الروابط بكل شيء هنا ، أي بشكل عام كل ما يمكن العثور عليه في نيم. إذا لم تجد ما تحتاجه في البرامج التعليمية والدليل ، فستجده بالتأكيد في الفهرس.
دروس ودروس
مساعدة
- IRC هو الموطن الرئيسي ... من نيميرز ، الذي يبث على Discord و Gitter . لم أستخدم IRC أبدًا (وما زلت لا أستخدمه). بشكل عام ، هذا اختيار غريب جدًا. لا يزال هناك حمامة البريد بالنسبة له ... حسنا ، يمزح.
- Nim forum ميزات المنتدى ضئيلة ، ولكن 1) هنا يمكنك العثور على الإجابة 2) هنا يمكنك طرح سؤال إذا كان البند 1 لا يعمل 3) واحتمال الإجابة أكثر من 50٪ 4) يجلس مطورو اللغات في المنتدى ويستجيبون بنشاط. بالمناسبة ، يتم كتابة المنتدى في نيم ، وبالتالي لا توجد وظيفة
- Nim telegram group - من الممكن طرح سؤال و [عدم] الحصول على إجابة.
- هناك أيضًا مجموعة برقية روسية ، إذا كنت تعبت من عدم الرغبة في سماع أي شيء عنها ، فيجب عليك الذهاب إلى هناك :) (مزحة جزئيًا)
ملعب
- ملعب نيم - هنا يمكنك تشغيل البرنامج على نيم مباشرة في المتصفح
- Nim docker cross-compiling - هنا يمكنك قراءة كيفية إطلاق صورة عامل ميناء وتجميع البرنامج لأنظمة أساسية مختلفة.
حزم
التبديل إلى نيم من لغات أخرى
ماذا تحب
ليس من المنطقي سرد جميع ميزات اللغة ، ولكن فيما يلي بعض الميزات:
كسورية التعقيد
نيم يوفر لك "كسورية من التعقيد." يمكنك كتابة رمز رفيع المستوى. يمكنك بعقب مع مؤشرات الخام والتمتع بكل attempt to read from nil
. يمكنك تضمين رمز C. يمكنك كتابة إدراج في المجمع . يمكنك كتابة الإجراءات (إرسال ثابت). لا يكفي - هناك "طرق" (إرسال ديناميكي). أكثر من ذلك؟ هناك الأدوية الجنيسة ، وهناك الأدوية البديلة التي تحاكي الوظائف. هناك قوالب (قوالب) - آلية بديلة ، لكن ليس مثل القيء كما في C ++ (هل هناك وحدات ماكرو - هل ما زالت مجرد استبدال للنص ، أم أنها شيء أكثر ذكاءً؟). هناك وحدات ماكرو ، في النهاية - إنها مثل IDDQD ، فهي تتيح وضع الله وتتيح لك العمل مباشرة مع AST واستبدال قطع من شجرة بناء الجملة حرفيًا ، أو توسيع اللغة بنفسك.
هذا هو ، على المستوى "العالي" ، يمكنك كتابة كلمات الجحيم والحزن كي لا يعرفها ، لكن لا أحد يمنعك من القيام بعمليات احتيال بأي تعقيد.
سرعة التنمية
منحنى التعلم ليس منحنى. هذا مباشر. عن طريق تثبيت nim ، ستبدأ عالم الترحيب الأول في الدقيقة الأولى ، وفي اليوم الأول ستكتب أداة مساعدة بسيطة. ولكن في غضون شهرين سيكون لديك شيء لتتعلمه. على سبيل المثال ، بدأت بالإجراءات ، ثم احتجت إلى طرق ، بعد فترة من الزمن كانت الأدوية المفيدة لي ، اكتشفت مؤخرًا قوالب بجمالها الكامل ، وفي الوقت نفسه لم أتطرق إلى وحدات الماكرو على الإطلاق. مقارنة مع نفس الصدأ أو c ++ ، فإن الدمج مع nim أسهل بكثير.
إدارة الحزمة
هناك مدير حزمة يسمى nimble يمكنه تثبيت وإلغاء تثبيت وإنشاء حزم وتحميل التبعيات. عند إنشاء الحزمة الخاصة بك (= مشروع) ، يمكنك كتابة مهام مختلفة في الذاكرة (باستخدام nimscript ، وهي مجموعة فرعية من nim منفذة على VM) ، على سبيل المثال ، إنشاء الوثائق ، تشغيل الاختبارات ، نسخ الأصول ، إلخ. Nimble لا يضع التبعيات الضرورية فحسب ، بل يسمح لك أيضًا بتهيئة بيئة العمل لمشروعك. وهذا هو ، ذكيا ، تقريبا ، CMake ، الذي لم يكتب من قبل المنحرفين ، ولكن من قبل الناس العاديين.
سهولة القراءة والتعبير
خارجيا ، يشبه نيم جدا بيثون مع تعليقات توضيحية ، على الرغم من أن نيم ليس بيثون على الإطلاق. سيتعين على بيثيونس أن ينسوا الكتابة الديناميكية والميراث والديكور والأفراح الأخرى ، ويعيدون هيكلة تفكيرهم بشكل عام. لا تحاول نقل تجربة الثعبان إلى نيم ، لأن الفرق كبير جدًا. في البداية ، أريد حقًا مجموعات غير متجانسة وتمزج مع الديكور. ولكن بعد ذلك بطريقة ما تعتاد على العيش في المشقة :)
فيما يلي مثال لبرنامج nim:
type NumberGenerator = object of Service # this service just generates some numbers NumberMessage = object of Message number: int proc run(self: NumberGenerator) = if not waitAvailable("calculator"): echo "Calculator is unavailable, shutting down" return for number in 0..<10: echo &"Sending number {number}" (ref NumberMessage)(number: number).send("calculator")
نمطية
كل شيء مقسم إلى وحدات نمطية يمكنك استيرادها كما تريد - لاستيراد أحرف معينة فقط ، أو كلها ما عدا معينة ، أو كلها ، أو لا شيء وإجبار المستخدم على تحديد المسار الكامل module.function()
، وكذلك الاستيراد تحت اسم مختلف. بالطبع ، كل هذا التنوع مفيد للغاية كحجة أخرى في النقاش "أي لغة البرمجة أفضل" ، وفي مشروعك سوف تكتب بهدوء import mymodule
ولا تذكر الخيارات الأخرى.
طريقة استدعاء بناء الجملة
يمكن تسجيل استدعاء وظيفة بطرق مختلفة:
double(2) double 2 2.double() 2.double
من ناحية ، يكتب الجميع الآن كما يحب (والجميع يحب ذلك بطرق مختلفة ، وبطبيعة الحال ، بطرق مختلفة حتى في إطار مشروع واحد). ولكن بعد ذلك ، يمكن كتابة جميع الوظائف على أنها استدعاء للطريقة ، مما يحسن بشكل كبير من قابلية القراءة. في الثعبان ، يمكن أن يكون:
list(set(some_list))
يمكن إعادة كتابة نفس الرمز في nim بطريقة منطقية أكثر:
some_list.set.list #
منظمة التحرير الفلسطينية
على الرغم من وجودها خارجها ، إلا أنها تختلف عن غيرها من الإيجابيات والأفعى: الكائنات والأساليب هي كيانات مختلفة ، وقد توجد في وحدات مختلفة. علاوة على ذلك ، يمكنك كتابة الأساليب الخاصة بك لأنواع أساسية مثل int
proc double(number: int): int = number * 2 echo $2.double() # prints "4"
من ناحية أخرى ، يوجد تغليف في nim (القاعدة الأولى للوحدة النمطية في nim هي عدم إخبار أي شخص عن المعرفات بدون علامة نجمية). فيما يلي مثال على وحدة نمطية قياسية:
# sharedtables.nim type SharedTable*[A, B] = object ## generic hash SharedTable data: KeyValuePairSeq[A, B] counter, dataLen: int lock: Lock
يتم SharedTable*
النوع SharedTable*
بعلامة النجمة ، مما يعني أنه "مرئي" في الوحدات النمطية الأخرى ويمكن استيراده. لكن data
counter
lock
أعضاء sharedtables.nim
، ولا يمكن الوصول إلى sharedtables.nim
من الخارج. لقد جعلني هذا سعيدًا جدًا عندما قررت كتابة بعض الوظائف الإضافية لنوع SharedTable
، مثل len
أو hasKey
، ووجدت أنه لا يمكنني الوصول إلى counter
أو data
، وكانت الطريقة الوحيدة "لتوسيع" SharedTable
هي كتابة ملفك الخاص ، مع bl
بشكل عام ، يتم استخدام الميراث في كثير من الأحيان أقل بكثير من نفس الثعبان (من تجربة شخصية) ، لأن هناك بناء جملة استدعاء الأسلوب (انظر أعلاه) ومتغيرات الكائنات (انظر أدناه). المسار نيم هو التكوين بدلا من الميراث. وينطبق الشيء نفسه على تعدد الأشكال: في نيم هناك طرق يمكن تجاوزها في الفصول اللاحقة ، ولكن يجب تحديد ذلك بشكل صريح أثناء التجميع باستخدام - --multimethods:on
flag. هذا ، افتراضيًا ، لا تعمل الطرق ، مما يشجع العمل قليلاً بدونها.
ترجمة وقت التنفيذ
Const - القدرة على حساب شيء ما في مرحلة التجميع و "خياطة" في ثنائي الناتجة. إنه رائع ومريح. بشكل عام ، لدى nim علاقة خاصة بـ "وقت التحويل البرمجي" ، فهناك حتى when
الكلمة الرئيسية - يبدو الأمر كما if
، ولكن المقارنة في مرحلة الترجمة. يمكنك كتابة شيء من هذا القبيل
when defined(SDL_VIDEO_DRIVER_WINDOWS): import windows ## oldwinapi lib elif defined(SDL_VIDEO_DRIVER_X11): import x11/x, x11/xlib ## x11 lib
هذا مناسب للغاية ، على الرغم من وجود قيود على ما يمكنك القيام به في مرحلة الترجمة (على سبيل المثال ، لا يمكنك إجراء مكالمات FFI).
نوع المرجع
نوع المرجع - هو مثيل لـ Shared_ptr في C ++ ، والذي سيتولى جامع البيانات المهملة معالجته. ولكن يمكنك أيضًا استدعاء جامع القمامة بنفسك في تلك اللحظات عندما يكون ذلك مناسبًا لك. أو يمكنك تجربة خيارات مختلفة لهواة جمع القمامة. أو يمكنك تعطيل أداة تجميع مجمعي البيانات المهملة تمامًا واستخدام مؤشرات عادية.
من الناحية المثالية ، إذا كنت لا تستخدم المؤشرات الأولية و FFI ، فمن غير المحتمل أن تحصل على أخطاء تجزئة. في الممارسة العملية ، حتى الآن دون FFI في أي مكان.
Lambdas
هناك إجراءات مجهولة المصدر (تُعرف أيضًا باسم لامدا في بيثون) ، ولكن على عكس بيثون في إجراء مجهول ، يمكنك استخدام العديد من العبارات:
someProc(callback=proc(a: int) -> int = var b = 5*a; result = a)
استثناءات
هناك استثناءات ، فهي غير مريحة للغاية: بيثون raise ValueError('bad value')
، نيم raise newException(ValueError, "bad value")
. لا شيء أكثر شيئًا غير عادي - جرّب ، أخيرًا ، كل شيء مثل أي شخص آخر. أنا ، بصفتي مؤيدًا للاستثناءات ، وليس رموز الأخطاء ، أفرح. بالمناسبة ، يمكنك الإشارة إلى الوظائف التي يمكن أن تقوم بها الاستثناءات ، وسيقوم المترجم بالتحقق من ذلك:
proc p(what: bool) {.raises: [IOError, OSError].} = if what: raise newException(IOError, "IO") else: raise newException(OSError, "OS")
الأدوية
الأدوية العامة معبرة جدًا ، على سبيل المثال ، يمكنك تحديد الأنواع المحتملة
proc onlyIntOrString[T: int|string](x, y: T) = discard # int string
ويمكنك تمرير نوع بشكل عام كمعلمة - يبدو وكأنه وظيفة عادية ، ولكن في الواقع عام:
proc p(a: typedesc; b: a) = discard # is roughly the same as: proc p[T](a: typedesc[T]; b: T) = discard # hence this is a valid call: p(int, 4) # as parameter 'a' requires a type, but 'b' requires a value.
قوالب
تشبه القوالب وحدات ماكرو في C ++ ، تم إجراؤها بشكل صحيح :) - يمكنك نقل كتل التعليمات البرمجية بأكملها بأمان إلى القوالب ، ولا تعتقد أن الاستبدال سوف يفسد شيئًا في الكود الخارجي (لكن يمكنك ، مرة أخرى ، لجعلها تصل الفوضى ، إذا كنت بحاجة حقا ل).
فيما يلي مثال app
القالب ، والذي ، بناءً على قيمة المتغير ، يستدعي إحدى كتل الشفرة:
template app*(serverCode: untyped, clientCode: untyped) = # ... case mode of client: clientCode of server: serverCode else: discard
مع do
يمكنني تمرير كتل كاملة إلى القالب ، على سبيل المثال:
app do: # serverCode echo "I'm server" serverProc() do: # clientCode echo "I'm client" clientProc()
قذيفة التفاعلية
إذا كنت بحاجة إلى اختبار شيء بسرعة ، أي القدرة على استدعاء "مترجم" أو "قذيفة نيم" (كما لو كنت تقوم بتشغيل python
بدون معلمات). للقيام بذلك ، استخدم الأمر nim secret
أو قم بتنزيل الحزمة inim .
FFI
FFI - القدرة على التفاعل مع مكتبات الطرف الثالث في C / C ++. لسوء الحظ ، لاستخدام مكتبة خارجية ، عليك أن تكتب غلافًا يشرح من أين وما الذي تريد الاستيراد منه. على سبيل المثال:
{.link: "/usr/lib/libOgreMain.so".} type ManualObjectSection* {.importcpp: "Ogre::ManualObject::ManualObjectSection", bycopy.} = object
هناك أدوات تجعل هذه العملية شبه آلية:
ما لا تحب
تعقيد
أشياء كثيرة جدا. تم تصور اللغة على أنها أضيق الحدود ، لكنها الآن بعيدة كل البعد عن الحقيقة. على سبيل المثال ، لماذا حصلنا على إعادة ترتيب الكود ؟!
وفرة
الكثير من الخراء: system.addInt - "تحويل عدد صحيح إلى تمثيل السلسلة وإلحاقه بنتيجة". يبدو لي أن هذه هي وظيفة مريحة للغاية ، وأنا استخدامها في كل مشروع. إليك ميزة أخرى مثيرة للاهتمام: fileExists and existFile ( https://forum.nim-lang.org/t/3636 )
لا توحيد
"لا يوجد سوى طريقة واحدة للقيام بشيء" - لا شيء على الإطلاق:
- الأسلوب استدعاء بناء الجملة - كتابة استدعاء دالة كما تريد
fmt
vs &
- camelCase و underscore_notation
- هذا و tHiS (المفسد: إنه نفس الشيء)
- وظيفة مقابل الإجراء مقابل القالب
الأخطاء (لا أكياس!)
هناك أخطاء ، حوالي 1400 . أو مجرد الذهاب إلى المنتدى - وجدوا باستمرار بعض الأخطاء.
استقرار
بالإضافة إلى الفقرة السابقة ، v1 يعني الاستقرار ، أليس كذلك؟ وهنا ينتقل مُنشئ لغة Araq إلى المنتدى ويقول: "أيها الرجال ، لقد حصلت على أداة تجميع سامة أخرى (سادسة) هنا ، إنها أبرد وأسرع وأصغر سنا ، تمنحك ذاكرة مشتركة للخيوط (ها ها ها ، وقبل ذلك عانيت و العكازات المستخدمة) ، تحميل فرع تطوير ومحاولة. " وكل هذا "واو ، كم هو رائع! وماذا يعني ذلك لمجرد البشر؟ هل نحن بحاجة الآن إلى تغيير كل الكود مرة أخرى؟" يبدو أنه ليس كذلك ، لذا أقوم بتحديث nim ، قم بتشغيل أداة تجميع مجمعي بيانات غير مقبولة - --gc:arc
وتعطل برنامجي في مكان ما في مرحلة تجميع رمز c ++ (أي ليس في nim ، ولكن في gcc):
/usr/lib/nim/system.nim:274:77: error: 'union pthread_cond_t' has no member named 'abi' 274 | result = x
عظيم! الآن ، بدلاً من كتابة كود جديد ، لا بد لي من إصلاح الكود القديم. لم يكن هذا ما كنت أركض عندما اخترت نيم؟
جميل أن أعرف أنني لست وحدي
طرق و multithreading
بشكل افتراضي ، يتم إيقاف تشغيل إشارات multimethods و مؤشرات الترابط - لن تقوم بذلك 2019 2020 كتابة تطبيق متعدد الخيوط مع طرق الغالبة؟! وكم هو رائع إذا تم إنشاء مكتبتك دون النظر في التدفقات ، ثم قام المستخدم بتشغيلها ... أوه نعم ، هناك براغمات رائعة {.inheritable.} و {.base.} للميراث حتى لا يكون الكود الخاص بك موجزا للغاية.
كائن المتغيرات
يمكنك تجنب الميراث باستخدام ما يسمى بدائل الكائن:
type CoordinateSystem = enum csCar, # Cartesian csCyl, # Cylindrical Coordinates = object case cs: CoordinateSystem: # cs is the coordinate discriminator of csCar: x: float y: float z: float of csCyl: r: float phi: float k: float
بناءً على قيمة cs
، ستكون إما حقول x و y و z أو r و phi و k متاحة لك.
ما هي العيوب؟
أولاً ، يتم حجز الذاكرة لـ "الخيار الأكبر" - بحيث يتم ضمان احتوائها في الذاكرة المخصصة للكائن.
ثانياً ، لا يزال الميراث أكثر مرونة - يمكنك دائمًا إنشاء سليل وإضافة المزيد من الحقول ، وفي متغير الكائن ، يتم تحديد جميع الحقول بشكل صارم في قسم واحد.
ثالثًا ، ما يثير غضبًا أكبر هو أنه لا يمكنك "إعادة استخدام" الحقول في أنواع مختلفة:
type # The 3 notations refer to the same 3-D entity, and some coordinates are shared CoordinateSystem = enum csCar, # Cartesian (x,y,z) csCyl, # Cylindrical (r,φ,z) Coordinates = object case cs: CoordinateSystem: # cs is the coordinate discriminator of csCar: x: float y: float z: float # z already defined here of csCyl: r: float phi: float z: float # fails to compile due to redefinition of z
لا تدوين
فقط للاقتباس :
- تفعل مع الأقواس هو بروك مجهول
- الاستغناء عن أقواس هو مجرد كتلة من التعليمات البرمجية
تعبير واحد يعني أشياء مختلفة ¯_ (ツ) _ / ¯
متى للاستخدام
لذلك ، لدينا وظائف ، والإجراءات ، والعقاقير ، والأنماط المتعددة ، والقوالب ، ووحدات الماكرو. متى يكون من الأفضل استخدام القالب ومتى يكون الإجراء؟ قالب أو عام؟ وظيفة أو إجراء؟ لذلك ، ماذا عن وحدات الماكرو؟ أعتقد أنك تحصل على هذه النقطة.
براغما مخصصة
هناك ديكورات في الثعبان يمكن تطبيقها حتى على الفصول ، وحتى على الوظائف.
هناك براغمات في نيم لهذا الغرض. وهنا هو ما:
رشيق
ما مات لا يستطيع الموت. في ذكيا ، مجموعة من المشاريع التي لم يتم تحديثها لفترة طويلة (وفي نيم أنها مثل الموت) - ولا تتم إزالتها. لا أحد يتابع هذا. من الواضح أنه متوافق مع الإصدارات السابقة ، "لا يمكنك فقط أخذ الحزمة وإزالتها من اللفت" ، ولكن لا يزال ... حسنًا ، شكرًا ، على الأقل لا يعجبك npm.
تجريد متسرب
يوجد قانون تجريد هولي - تستخدم نوعًا من التجريد ، لكن عاجلاً أم آجلاً ستجد "فجوة" فيه ستقودك إلى مستوى أقل. Nim عبارة عن مجموعة من C و C ++ ، وسوف تفشل هناك عاجلاً أم آجلاً. أراهن أنك لا تحب ذلك هناك؟
Error: execution of an external compiler program 'g++ -c -w -w -fpermissive -pthread -I/usr/lib/nim -I/home/user/c4/systems/network -o /home/user/.cache/nim/enet_d/@m..@s..@s..@s..@s..@s..@s.nimble@spkgs@smsgpack4nim-0.3.0@smsgpack4nim.nim.cpp:6987:136: note: initializing argument 2 of 'void unpack_type__k2dhaoojunqoSwgmQ9bNNug(tyObject_MsgStreamcolonObjectType___kto5qgghQl207nm2KQZEDA*, NU&)' 6987 | N_LIB_PRIVATE N_NIMCALL(void, unpack_type__k2dhaoojunqoSwgmQ9bNNug)(tyObject_MsgStreamcolonObjectType___kto5qgghQl207nm2KQZEDA* s, NU& val) { nimfr_("unpack_type", "/home/user/.nimble/pkgs/msgpack4nim-0.3.0/msgpack4nim.nim"); |
tyObject_MsgStreamcolonObjectType ___ kto5qgghQl207nm2KQZEDA * ق، NU وفال) {nimfr _ ( "unpack_type"، "/home/user/.nimble/pkgs/msgpack4nim-0.3.0/msgpack4nim.nim")؛ Error: execution of an external compiler program 'g++ -c -w -w -fpermissive -pthread -I/usr/lib/nim -I/home/user/c4/systems/network -o /home/user/.cache/nim/enet_d/@m..@s..@s..@s..@s..@s..@s.nimble@spkgs@smsgpack4nim-0.3.0@smsgpack4nim.nim.cpp:6987:136: note: initializing argument 2 of 'void unpack_type__k2dhaoojunqoSwgmQ9bNNug(tyObject_MsgStreamcolonObjectType___kto5qgghQl207nm2KQZEDA*, NU&)' 6987 | N_LIB_PRIVATE N_NIMCALL(void, unpack_type__k2dhaoojunqoSwgmQ9bNNug)(tyObject_MsgStreamcolonObjectType___kto5qgghQl207nm2KQZEDA* s, NU& val) { nimfr_("unpack_type", "/home/user/.nimble/pkgs/msgpack4nim-0.3.0/msgpack4nim.nim"); |
/usr/bin/ld: /home/user/.cache/nim/enet_d/stdlib_dollars.nim.cpp.o: in function `dollar___uR9bMx2FZlD8AoPom9cVY9ctA(tyObject_ConnectMessage__e5GUVMJGtJeVjEZUTYbwnA*)': stdlib_dollars.nim.cpp:(.text+0x229): undefined reference to `resizeString(NimStringDesc*, long)' /usr/bin/ld: stdlib_dollars.nim.cpp:(.text+0x267): undefined reference to `resizeString(NimStringDesc*, long)' /usr/bin/ld: stdlib_dollars.nim.cpp:(.text+0x2a2): undefined reference to `resizeString(NimStringDesc*, long)'
هكذا
أنا مبرمج غبي. لا أريد أن أعرف كيف يعمل GC ، وما هو موجود وكيف يرتبط ، وأين يتم تخزينه مؤقتًا ، وكيف تتم إزالة القمامة. إنها مثل سيارة - من حيث المبدأ ، أنا أعرف كيف تعمل ، وقليلًا عن محاذاة العجلة ، وقليلًا عن علبة التروس ، أحتاج إلى ملء الزيت والأشياء ، لكن بشكل عام أريد فقط أن أجلس وأذهب (سريعًا) إلى الحفلة. الجهاز ليس هدفًا ، بل وسيلة لتحقيق غاية. إذا تعطلت ، فأنا لا أريد الدخول في الغطاء ، ولكن فقط أخذه إلى الخدمة (بمعنى ، سأفتح المشكلة على جيثب) ، وسيكون من الرائع أن يتم إصلاحها بسرعة.
نيم كان من المفترض أن يكون مثل هذا الجهاز. في جزء منه ، أصبح ، لكن في الوقت نفسه ، عندما أسابق على طول هذا الطريق السريع على هذه السيارة ، تسقط العجلة ، بينما تشير المرآة الخلفية إلى الأمام. يركض المهندسون بعدي ويعلقون شيئًا سريعًا ("أصبحت سيارتك الآن أسرع مع هذا المفسد الجديد") ، ولكن من هذا ينهار الصندوق. وانت تعرف ماذا؟ ما زلت لعنة مثل هذه السيارة ، لأن هذا هو أفضل ما في جميع السيارات التي رأيتها.