0Pricing
Scala for Backend Engineering & Functional Programming · درس

Either لمعالجة الأخطاء

Left وRight

Either لمعالجة الأخطاء درس مجاني في Scala for Backend Engineering & Functional Programming على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Scala for Backend Engineering & Functional Programming، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Scala for Backend Engineering & Functional Programming 4 دروس في المجموع.

لماذا Either؟

يمثل Either قيمة يمكن أن تكون إحدى نتيجتين محتملتين. وهو الأسلوب الاصطلاحي لتمثيل العمليات الحسابية التي قد تفشل مع تقديم معلومات عن سبب الفشل.

  • يحتوي Left تقليديًا على الخطأ.
  • يحتوي Right تقليديًا على قيمة النجاح.

وعلى خلاف Option، الذي يخبركم فقط بأن شيئًا ما مفقود، يخبركم Either بما حدث من خطأ.

نوع Either

إن Either[A, B] سمة مختومة لها نوعان فرعيان: Left[A] وRight[B].

وسيلة التذكّر: Right is right (أي صحيح)، أما Left فهو الخطأ. يتيح هذا الاصطلاح لـ map وflatMap العمل تلقائيًا على جانب النجاح.

val ok: Either[String, Int] = Right(42)
val err: Either[String, Int] = Left("boom")
println(ok)
println(err)

إرجاع Either من دالة

تعيد الدالة التي قد تفشل قيمة Either بدلًا من طرح استثناء. ويمكن عندئذٍ للجهة المستدعية معالجة النتيجتين صراحةً.

object Main {
  def parseAge(s: String): Either[String, Int] =
    s.toIntOption match {
      case Some(n) if n >= 0 => Right(n)
      case Some(_)          => Left("age cannot be negative")
      case None             => Left("not a number")
    }

  def main(args: Array[String]): Unit = {
    println(parseAge("30"))
    println(parseAge("-5"))
    println(parseAge("x"))
  }
}

مطابقة الأنماط مع Either

أكثر الطرق مباشرةً لاستهلاك Either هي مطابقة الأنماط. إذ تعالجون Left وRight كلًّا على حدة.

@main def run(): Unit = {
  val result: Either[String, Int] = Right(10)
  val msg = result match {
    case Right(value) => s"Got value: $value"
    case Left(error)  => s"Failed: $error"
  }
  println(msg)
}

‏fold: دمج الجانبين

تستقبل fold دالتين: واحدة لـ Left وأخرى لـ Right، وتنتج نتيجة واحدة من نوع مشترك.

وهي بديل موجز لمطابقة الأنماط عندما تريدون الحصول على قيمة.

@main def run(): Unit = {
  val r: Either[String, Int] = Right(7)
  val label = r.fold(
    err => s"error: $err",
    num => s"double is ${num * 2}"
  )
  println(label)
}

تعمل map على Right

تحوّل map قيمة Right وتترك Left من دون تغيير. وهذا هو سلوك Either المنحاز إلى اليمين في Scala (منذ الإصدار 2.12).

@main def run(): Unit = {
  val ok: Either[String, Int]  = Right(5)
  val no: Either[String, Int]  = Left("missing")
  println(ok.map(_ + 1))
  println(no.map(_ + 1))
}

‏getOrElse والقيم الافتراضية

تستخرج getOrElse قيمة Right أو تعيد قيمة بديلة عندما تكون Either من نوع Left.

@main def run(): Unit = {
  val ok: Either[String, Int] = Right(99)
  val no: Either[String, Int] = Left("oops")
  println(ok.getOrElse(0))
  println(no.getOrElse(0))
}

‏swap: تبديل الجانبين

تبدّل swap بين Left وRight. ويفيد ذلك عندما تريدون العمل على جانب الخطأ باستخدام الدوال المنحازة إلى اليمين.

@main def run(): Unit = {
  val err: Either[String, Int] = Left("bad input")
  val swapped = err.swap.map(_.toUpperCase)
  println(swapped)
}

‏isLeft وisRight

تتيح فحوصات منطقية سريعة التفرّع من دون إجراء مطابقة أنماط كاملة.

  • تعيد isRight القيمة true عند النجاح.
  • تعيد isLeft القيمة true عند حدوث خطأ.
@main def run(): Unit = {
  val r: Either[String, Int] = Right(1)
  println(r.isRight)
  println(r.isLeft)
}

‏toOption: تجاهل الخطأ

عندما لا تعودون تهتمون بسبب الفشل، تحوّل toOption قيمة Either إلى Option: تصبح Right(x) هي Some(x)، وتصبح Left(_) هي None.

@main def run(): Unit = {
  val ok: Either[String, Int] = Right(3)
  val no: Either[String, Int] = Left("err")
  println(ok.toOption)
  println(no.toOption)
}

مثال على التحقق

لنجمع كل ذلك: تحقّقوا من اسم مستخدم، وأعيدوا خطأً ذا نوع محدد عند الفشل.

object Main {
  def validate(name: String): Either[String, String] =
    if (name.isEmpty) Left("empty name")
    else if (name.length > 10) Left("name too long")
    else Right(name)

  def main(args: Array[String]): Unit = {
    println(validate("alice"))
    println(validate(""))
    println(validate("verylongusername"))
  }
}

تحقق سريع

اختبروا فهمكم لاصطلاحات Either.

مراجعة

لقد تعلّمتم تمثيل الأخطاء باستخدام Either:

  • Right = نجاح، وLeft = خطأ (مع الانحياز إلى اليمين).
  • استهلكوه باستخدام مطابقة الأنماط أو fold.
  • حوّلوا قيمة النجاح باستخدام map، وقدّموا قيمًا افتراضية باستخدام getOrElse.
  • بدّلوا الجانبين باستخدام swap، وحوّلوا النوع باستخدام toOption.

سوف تتعاملون بعد ذلك مع الاستثناءات باستخدام Try.

الأسئلة الشائعة

هل درس «Either لمعالجة الأخطاء» مجاني؟

نعم — نص درس «Either لمعالجة الأخطاء» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Scala for Backend Engineering & Functional Programming، انتقل إلى CoddyKit PRO. تتضمن دورة Scala for Backend Engineering & Functional Programming 4 دروس في المجموع.

ماذا ستتعلم في «Either لمعالجة الأخطاء»؟

Left وRight تتمرن على Scala for Backend Engineering & Functional Programming مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Scala for Backend Engineering & Functional Programming؟

لا تُشترط خبرة سابقة. Scala for Backend Engineering & Functional Programming على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «Either لمعالجة الأخطاء»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Scala for Backend Engineering & Functional Programming هذا؟

نعم. كل درس في Scala for Backend Engineering & Functional Programming يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. Either لمعالجة الأخطاء
  2. Try وSuccess وFailure
  3. تركيب Either
  4. التحويل بين الأنواع
← العودة إلى Scala for Backend Engineering & Functional Programming