استدلال نوع Scala مع _ Place Holder
-
28-09-2019 - |
سؤال
List("This","is","Scala").foreach(a => print(a+" "))
يجمع بشكل جيد ، لكن
List("This","is","Scala").foreach(print(_+" "))
فشل في الشكوى من نوع المعلمة المفقودة. لم أستطع معرفة سبب فشلها.
تحرير: قصدت طباعة لا println - ليس أنها تحدث فرقًا منطقيًا.
المحلول
المشكلة هي أن هذا
List("This","is","Scala").foreach(print(_+" "))
لا يعادل
List("This","is","Scala").foreach(a => print(a+" "))
لكن من أجل
List("This","is","Scala").foreach(print(a => a+" "))
الآن ، دعونا نرى توقيع النوع foreach
:
def foreach [B] (f: (A) ⇒ B) : Unit
أين A
هو معلمة النوع من List
بحد ذاتها. لأن لدينا أ List[String]
, ، يعرف المترجم أن المرء يتعين على المرء أن يمر إليه foreach
أ Function[String, B]
.
في a => print(a+" ")
نوع من a
معروف بالفعل: String
.
في print(a => a+" ")
هناك مشكلة print
ليس Function
. ومع ذلك ، لم يفكر المترجم في ذلك بعد - لا يزال يحاول التجميع a => a+" "
. لذلك دعونا نلقي نظرة على نوع Predef.print
:
def print (x: Any) : Unit
لذا a => a+" "
يجب أن يكون من النوع Any
, ، وهذا يعني ، بالطبع أنه يمكن أن يكون أي شيء. لا يساعد المترجم في تأكيد نوع من a
هو. وهذا لا يهم حقًا ، لأنك لا تريد طباعة ملف Function
في المقام الأول.
نصائح أخرى
يقرأ سكالا (_+" ")
كما x => x+" "
. ولكن println
لا يحتوي على أي معلومات عن النوع لمساعدة التحويل البرمجي على تخمين نوع النوع x
قد يكون ، لذلك يعطي هذا الخطأ.
ما تريد أن تفعله هو ملاحظة ذلك println
لم تعمل وتتكرر للخلف وجربها مرة أخرى من أجل foreach
. لكنها لا تستطيع فعل ذلك: println
يمكن أن تأخذ أي حجة ، بما في ذلك وظيفة ، لذلك x => x+" "
هو شيء صحيح تماما ل println
لمحاولة الطباعة.
(وحتى في حالة يمكن أن يكون فيها من الناحية النظرية ، لا يفعل ذلك عمومًا.)