إذا كان نوع شيء في أسفل التسلسل الهرمي للفئة، فلماذا لا يمكنني الاتصال بأي طريقة يمكن تصورها على ذلك؟
سؤال
نوع scala Nothing
يمثل (كما أفهمها) الجزء السفلي من التسلسل الهرمي للنوع، كما يشير من الرمز ⊥. إنه، Nothing
هو نوع فرعي من أي نوع معين. شرط ل Nothing
النوع هو وأوضح جيدا من قبل جيمس اليري لأولئك منا دون خلفية نظرية في نظرية النوع!
لذلك سؤالي هو، إذا Nothing
هو نوع فرعي من كل نوع، لماذا لا يمكنني استدعاء أي طرق نوع Nothing
ب من الواضح، لا أستطيع إنشاء شيء سوى لماذا لا تترجم ما يلي؟
var n: Nothing = _
def main(args: Array[String]) {
println(n.length) //compile error: value length is not a member of Nothing
}
بالتأكيد كما Nothing
هو نوع فرعي من String
هذا يجب أن يكون على ما يرام؟ لاحظ أن ما يلي يجمع بشكل جيد!
var n: Nothing = _
def foo(s: String) : Int = s.length
def main(args: Array[String]) {
println(foo(n))
}
كما يفعل:
def main(args: Array[String]) {
println(n.asInstanceOf[String].length)
}
المحلول
بينما Nothing
هو نوع فرعي من كل شيء، لا يرث أي طريقة باستثناء هؤلاء في Any
. وبعد هذا بسبب Nothing
أكثر جاهزة نحو النهاية الوظيفية للغة. من الضروري لأشياء مثل Option
و List
, ، ولكن فقط ك يكتب, ، ليس كصف.
التمييز هنا غريب بعض الشيء بالنسبة لأولئك الذين يأتون من خلفية موجهة نحو الكائنات، ولكن الحقيقة هي أن الفرعية الفرعية كمفهوم متميز جدا عن OOP. منحت، الموجه نحو الكائنات يعني حقا الفرعي الفرعي في شكل ما، ولكن العكس غير صحيح. بنيامين بيرس أنواع لغات البرمجة هل وظيفة جيدة في تقديم اللغة F_ (وضوحا "F Sub")، والذي يعمل بمثابة مثال على حد أدنى بلغة ذات فرعي (ولكن ليس OO).
الآن، مع كل ما قال، أوافق على أن حقيقة ذلك Nothing
هو المناعة من قواعد الميراث الطبيعية لا يبدو غير متسقة بعض الشيء. ومع ذلك، من وجهة نظر نظرية، فإنه منطقي مثالي.
نصائح أخرى
أقترح - أرى - أحبذ Nothing
يمكن أن تقبل أي طريقة، وإجراء عملية قياسية على كل منهم (رمي استثناء). لن يكون ذلك مفيدا للغاية.
من خلال تقديم خطأ في الترجمة، تحذر المحول البرمجي من المبرمج الذي لا يريده نوعه، Nothing
, ، استنتج بطريقة أو بأخرى في نقطة معينة في القانون.
تستطيع الاتصال toString
تشغيل Nothing
متغير بسبب ذلك devintion:
final trait Nothing extends Any
و Tostring عضو Any
. وبعد أعتقد أن تعامل مترجم Scala Nothing
في حدود النوع فقط ويعاملها مثل أي سمة أخرى على جميع الحالات. ترك استدعاء أي طريقة على المتغير مع نوع Nothing
سيكون غريبا جدا وأعتقد.