سؤال

أنا جديد تمامًا على لغة برمجة Scala ، وكنت أحاول شيئًا تمسك به في ذهني بينما كنت أتابع ملاحظات المحاضرة في هنا.

أعتقد أنني لا أستطيع أن أفهم حقًا كيف يعمل مشغل Cons ، إليك بعض الأشياء التي جربتها:

لقد قمت بإنشاء مولد أرقام عشوائي زائفة ، ثم حاولت إنشاء قائمة ذات قيمة عشوائية واحدة:

scala> val gen = new java.util.Random
gen: java.util.Random = java.util.Random@1b27332

scala> gen nextInt 3 :: Nil
<console>:7: error: type mismatch;
 found   : List[Int]
 required: Int
       gen nextInt 3 :: Nil
                     ^

لكنها حاولت تمرير قائمة (3) إلى طريقة NextNT. عندما استخدمت parathes ، لم تكن هناك مشكلة

scala> (gen nextInt 3) :: Nil
res69: List[Int] = List(1)

كنت فضوليًا بشأن أمر التنفيذ ، لذلك قمت بإنشاء وظيفة للتحقق منها

scala> def pr(i:Int):Int = { println(i); i }
pr: (i: Int)Int

scala> pr(1) :: pr(2) :: pr(3) :: Nil
1
2
3
res71: List[Int] = List(1, 2, 3)

كما هو موضح في المخرجات ، يكون ترتيب التنفيذ هو نفسه ترتيب المظهر. ثم اعتقدت أن الأمر قد يكون عن وظيفة "NextInt" ، ثم حاولت المتابعة:

scala> 1 + 2 :: Nil
res72: List[Int] = List(3)

تم تنفيذها أولاً ، وبعد تنفيذ السلبيات. إذن هذا هو السؤال: ما هو الفرق بين gen nextInt 3 :: Nil و 1 + 2 :: Nil?

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

المحلول

هناك شيئان يثيران القلق هنا: الأولوية و ثبات. كما ذكر Sepp2k ، يشرح هذا السؤال على Stack Overflow الأسبقية ، واعتقد أن القواعد ، كما هو مقتبس ، ليست كاملة بما فيه الكفاية ، وكانت هناك تغييرات صغيرة جدًا من Scala 2.7 إلى Scala 2.8. الاختلافات تتعلق في الغالب المشغلين ينتهيون =, ، على أية حال.

أما بالنسبة لل ثبات, ، يتم قراءة كل شيء تقريبًا في Scala من اليسار إلى اليمين ، وهو ما يستخدمه المبرمجين. في Scala ، ومع ذلك ، ينتهي المشغلون : تقرأ يمينًا إلى اليسار.

خذ ، إذن ، هذا المثال:

1 + 2 :: Nil

أولا ، الأسبقية. ما هو أكثر الأسبقية ، + أو :؟ وفقا للجدول ، + له الأسبقية :, ، لذلك يتم الإضافة أولاً. لذلك ، فإن التعبير يساوي هذا:

((1).+(2)) :: Nil

الآن ليس هناك صراع الأسبقية ، ولكن منذ ذلك الحين :: ينتهي :, ، لديها ثبات مختلف. تتم قراءة اليمين إلى اليسار ، لذلك:

Nil.::((1).+(2))

من ناحية أخرى ، في هذا:

gen nextInt 3 :: Nil

المشغل :: له الأسبقية nextInt, ، لان : له الأسبقية على جميع الحروف. لذلك ، وتذكر ثباته ، يصبح:

gen nextInt Nil.::(3)

الذي يصبح ثم

gen.nextInt(Nil.::(3))

عند هذه النقطة ، يكون الخطأ واضحًا.

ملاحظة: أنا أكتب (1).+(2) بدلاً من 1.+(2) لأنه ، في وقت كتابة هذا التقرير ، 1. يتم تفسيره على أنه رقم مزدوج ، ويصنع 1.+(2) تعبير Infix يضيف 1.0 إلى 2. يتم إهمال هذا الجملة اعتبارًا من Scala 2.10.0 ، وربما لن يكون موجودًا على Scala 2.11.

نصائح أخرى

إنه يتعلق بالأسبقية وليس أمر التنفيذ. + له أسبقية أعلى من ::, ، لذا a + b :: c أخر من (a + b) :: c. ومع ذلك ، فإن مكالمات طريقة Infix بأسماء منتظمة لها أسبقية أقل ، لذلك a foo b c أخر من a foo (b c).

نرى هذا السؤال لقائمة المشغلين التي طلبها أسباقهم في سكالا.

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