سؤال

كيف المقصود خيار العمل موناد؟ أنا أتصفح Scala API وهناك مثال (أعني الثاني) ،

بسبب كيفية عمل الفهم ، إذا لم يتم إرجاع أي شيء من request.getParameter ، فإن التعبير بأكمله ينتج عنه لا شيء

لكن عندما أحاول هذا الرمز:

 val upper = for {
   name <- None //request.getParameter("name")
   trimmed <- Some(name.trim)
   upper <- Some(trimmed.toUpperCase) if trimmed.length != 0
 } yield upper
 println(upper.getOrElse(""))

أحصل على خطأ تجميع. كيف من المفترض ان يعمل هذا؟

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

المحلول

تحصل على خطأ في المترجم بسبب هذا

  name <- None

بهذه الطريقة ، نوع من None تم تعيينه على None.type والمتغير name يتم استنتاج ليكون من النوع Nothing. (أي ، سيكون هذا النوع إذا كان موجودًا بالفعل ، لكن من الواضح أن الفهم لا يحصل حتى على إنشائه في وقت التشغيل.) لذلك لا توجد طريقة name.trim موجود ولن يجمع.

إذا كان لديك request.getParameter("name") متاح ، سيكون نوعه Option[String], name من المحتمل أن يكون له نوع String و name.trim سوف تجمع.

يمكنك العمل حول هذا من خلال تحديد نوع من None:

  name <- None: Option[String]

نصائح أخرى

للتوسع في إجابة كيفن ، يمكنك تجنب التغلب على القيم Some() باستخدام = المشغل بدلاً من <- المشغل أو العامل:

val upper = for {
   name <- None: Option[String] //request.getParameter("name")
   trimmed = name.trim
   upper = trimmed.toUpperCase if trimmed nonEmpty
} yield upper

سوف يجمع الفهم إلى شيء مشابه جدًا لإصدار كيفن ، لكنني غالبًا ما أجد أنه أكثر وضوحًا للاستخدام map و filter صراحة لتجنب الفوضى (على سبيل المثال أسماء متغيرة إضافية) لا تضيف شيئًا إلى المحتوى الدلالي للتعبير.

للتوسع في إجابة Debilski ، لا تحتاج أيضًا إلى لف القيم اللاحقة صراحة في Some(), ، القيمة الوحيدة التي تقوم بها بالفعل هي النسخة الأصلية name.

سيكون النهج الأفضل هو استخدام map و filter العمليات مباشرة بدلاً من التفريغ:

ملاحظة: خلف الكواليس ، سيقوم برنامج التحويل البرمجي Scala بتحويل الفهم إلى مزيج من الخريطة/الفلتر/المرشح على أي حال ، لذلك لن يكون هذا النهج أقل كفاءة من الفهجة ، وقد يكون أكثر كفاءة

def clean(x:Option[String]) = x map { _.trim.toUpperCase } filterNot { _.isEmpty }

val param = None : Option[String] // request.getParameter("name")
println( clean(param).getOrElse("") )
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top