لماذا يقوم عامل التشغيل && بإنتاج نوع المعامل الثاني

StackOverflow https://stackoverflow.com//questions/12693787

  •  12-12-2019
  •  | 
  •  

سؤال

تنص مواصفات TypeScript في الفقرة 4.15.6 على && المشغل أو العامل:

يسمح عامل التشغيل && للمعاملات بأن تكون من أي نوع وينتج ملف نتيجة من نفس نوع المعامل الثاني.

في جافا سكريبت، && يقوم عامل التشغيل بإرجاع المعامل الأول إذا كان خطأ، وإلا فإنه يقوم بإرجاع المعامل الثاني (انظر ECMA-262 §11.11).

وهذا يعني أنه إذا كان المعامل الأيسر خطأ، && سيُرجع قيمة تطابق نوع المعامل الأيسر.على سبيل المثال،

typeof ( false && {}      ) === "boolean" // true
typeof ( ''    && 1       ) === "string"  // true
typeof ( null  && "hello" ) === "object"  // true
typeof ( NaN   && true    ) === "number"  // true

الآلة الكاتبة، وفقًا للقاعدة المذكورة أعلاه، ستكون كذلك بشكل غير صحيح التنبؤ بأنواع التعبيرات المذكورة أعلاه Object, Number, String و Boolean, ، على التوالى.

هل فاتني شيء؟هل هناك سبب وجيه لجعل نوع && هل يتطابق التعبير مع نوع المعامل الثاني؟ألا ينبغي أن يتصرف نوع النتيجة مثل || عامل التشغيل، وإرجاع أفضل نوع شائع بين المعاملين، و Any إذا لم يكن هناك أفضل نوع مشترك؟

هل كانت مفيدة؟

المحلول

باختصار، لا يوجد حل هنا يرضي الجميع.

خذ بعين الاعتبار هذا المصطلح الشائع:

var customer = GetCustomer(...); // of type 'Customer'
var address = customer && customer.address;
if(address) {
    printAddressLabel(address); // Signature: (Address) => void
} else {
    // Couldn't find the customer or the customer has no address on file
}

سيكون أمرًا ضعيفًا جدًا أن تستسلم وتقرر أن "العنوان" هو "أي" لأنه لا يوجد أفضل نوع مشترك بين العميل والعنوان.

في معظم الحالات التي يتم فيها استخدام عامل التشغيل &&، يتم استخدام أي من النوعين بالفعل match، أو && يتم استخدامه بطريقة دمج القيمة كما هو مذكور أعلاه.وفي كلتا الحالتين، فإن إرجاع نوع المعامل الصحيح يمنح المستخدم النوع المتوقع.

على الرغم من أن أمان النوع ينهار من الناحية الفنية في هذه المرحلة، إلا أنه لا يفعل ذلك بطريقة من المحتمل أن تؤدي إلى حدوث خطأ.إما أنك ستختبر القيمة الناتجة للصدق (وفي هذه الحالة يكون النوع غير ذي صلة إلى حد ما)، أو أنك ستستخدم المعامل الصحيح المفترض لبعض العمليات (المثال أعلاه يقوم بكلا الأمرين).

إذا نظرنا إلى الأمثلة التي ذكرتها وتظاهرنا بأن المعامل الأيسر صحيح أو خطأ بشكل غير محدد، ثم حاولنا كتابة تعليمات برمجية معقولة تعمل على القيمة المرجعة، يصبح الأمر أكثر وضوحًا - ليس هناك الكثير مما يمكنك فعله يفعل مع "خطأ && {}" الذي لا يدخل بالفعل في موضع حجة "أي" أو اختبار الصدق.


إضافة

وبما أن بعض الناس لم يقتنعوا بما ورد أعلاه، فإليك تفسيرًا مختلفًا.

دعونا نتظاهر للحظة أن نظام كتابة TypeScript أضاف ثلاثة أنواع جديدة: Truthy<T>, Falsy<T>, ، و Maybe<T>, ، يمثل قيم الصدق/الخطأ المحتملة للنوع T.قواعد هذه الأنواع هي كما يلي:

  1. Truthy<T> يتصرف بالضبط مثل T
  2. لا يمكنك الوصول إلى أي خصائص Falsy<T>
  3. تعبير عن النوع Maybe<T>, ، عند استخدامها كشرط في if كتلة، تصبح Truthy<T> في جسد ذلك الشيء نفسه if كتلة و أ Falsy<T> في ال else حاجز

وهذا من شأنه أن يتيح لك القيام بأشياء مثل هذا:

function fn(x: Maybe<Customer>) {
   if(x) {
      console.log(x.address); // OK
   } else {
      console.log(x.phone); // Error: x is definitely falsy
   }
   console.log(x.name); // Warning: x might be falsy!
}

جيد جدا حتى الآن.يمكننا الآن معرفة قواعد الكتابة للمشغل &&.

  • Truthy<T> && x يجب أن يكون خطأ - إذا كان الجانب الأيسر معروفًا بأنه صادق، فيجب أن تكون قد كتبت للتو x
  • Falsy<T> && x يجب أن يكون خطأ - إذا كان الجانب الأيسر معروفا بأنه كاذب، x هو رمز لا يمكن الوصول إليه
  • Maybe<T> && x ينبغي أن تنتج ...ماذا؟

نحن نعرف النتيجة Maybe<T> && x ستكون إما قيمة زائفة من النوع T, ، أو x.لا يمكنها أن تنتج Truthy<T> (إلا إذا T == النوع x وفي هذه الحالة تكون هذه المناقشة بأكملها موضع نقاش).دعونا نسمي هذا النوع الجديد Falsy<T> XOR Maybe<U>.

ما ينبغي أن قواعد Falsy<T> XOR Maybe<U> يكون؟

  • من الواضح أنه لا يمكنك استخدام خصائص T عليه.إذا كانت القيمة من النوع T, ، فهو زائف، وغير آمن للاستخدام.
  • يجب أن تكون قادرًا على استخدامه ك Maybe<U>, ، منذ Falsy<T> و Falsy<U> لديهم نفس السلوكيات
  • لا يجب أن تكون قادرًا على استخدام خصائص U, ، لأن القيمة لا تزال غير صحيحة.
  • إذا كنت تستخدمه في if اختبار، ثم ينبغي أن تصبح Truthy<U> في كتلة ذلك if إفادة

بعبارة أخرى، Falsy<T> XOR Maybe<U> يكون Maybe<U>.ويتبع كل نفس القواعد.لا تحتاج إلى تعقيد نظام الكتابة على الإطلاق هنا بإضافة هذا الغريب XOR النوع، لأن النوع الذي يناسب جميع المواصفات التي تحتاجها موجود بالفعل.

هذا يشبه إلى حد ما إعطاء شخص ما صندوقًا والقول "هذا إما صندوق فارغ من القمامة، أو صندوق كامل من المواد القابلة لإعادة التدوير".يمكنك تفريغ محتويات الصندوق بأمان في سلة إعادة التدوير.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top