Macros عملية
حالات الاستخدام
Macros عملية درس مجاني في Scala for Backend Engineering & Functional Programming على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Scala for Backend Engineering & Functional Programming، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Scala for Backend Engineering & Functional Programming 4 دروس في المجموع.
الماكروهات في العالم الحقيقي
بعيدًا عن الأمثلة البسيطة، تحل الماكروهات مشكلات عملية مثل التقاط سياق المصدر، واشتقاق type classes، والتحقق من القيم الحرفية، وإنشاء كود خالٍ من الشيفرة النمطية.
حالة استخدام: assert مع رسالة
يمكن لماكرو التقاط النص المصدري للشرط الفاشل وإنشاء رسالة مفيدة لـ assert تلقائيًا.
import scala.quoted.*
inline def myAssert(inline cond: Boolean): Unit =
${ assertImpl('cond) }التقاط الكود المصدري
داخل الماكرو، تُرجع cond.show (عبر واجهة reflect) المصدر الحرفي للتعبير، ثم تُدرجه في رسالة الخطأ.
import scala.quoted.*
def assertImpl(cond: Expr[Boolean])(using q: Quotes): Expr[Unit] = {
import q.reflect.*
val src = Expr(cond.asTerm.show)
'{ if (!${ cond }) throw new AssertionError("failed: " + ${ src }) }
}حالة استخدام: التحقق وقت الترجمة
تحقّق من قيمة حرفية، مثل تعبير نمطي أو رقم منفذ، وقت الترجمة حتى لا تصل القيم غير الصالحة إلى وقت التشغيل.
import scala.quoted.*
inline def port(inline n: Int): Int = ${ portImpl('n) }إيقاف التنفيذ عند الإدخال غير الصالح
استخرج القيمة الحرفية، وتحقّق منها، واستدعِ report.errorAndAbort للقيم غير الصالحة، لتحويل خطأ وقت التشغيل إلى خطأ ترجمة.
import scala.quoted.*
def portImpl(n: Expr[Int])(using q: Quotes): Expr[Int] = {
import q.reflect.*
val v = n.valueOrAbort
if (v < 1 || v > 65535) report.errorAndAbort("invalid port")
n
}حالة استخدام: اشتقاق Typeclass
يمكن للماكروهات، غالبًا عبر inline وscala.deriving.Mirror، إنشاء مثيلات type class مثل مشفّرات JSON لأي case class دون شيفرة نمطية.
import scala.deriving.Mirror
trait Show[T] { def show(t: T): String }
inline def derived[T](using Mirror.Of[T]): Show[T] = ???استخدام Mirror
تكشف Mirror أنواع حقول المنتج وتسمياتها وقت الترجمة. وبدمجها مع inline، يمكنك التكرار على الحقول لبناء مثيل.
import scala.deriving.*
import scala.compiletime.*
inline def labels[T](using m: Mirror.ProductOf[T]): List[String] =
constValueTuple[m.MirroredElemLabels].toList.map(_.toString)حالة استخدام: التسجيل مع الموضع
يمكن لماكرو قراءة Position من واجهة reflect لإرفاق اسم الملف ورقم السطر برسائل السجل دون تكلفة وقت التشغيل.
import scala.quoted.*
def posImpl(using q: Quotes): Expr[String] = {
import q.reflect.*
val p = Position.ofMacroExpansion
Expr(s"${p.sourceFile.name}:${p.startLine + 1}")
}متى لا تستخدم الماكروهات
الماكروهات قوية، لكنها مكلفة في الصيانة وتصحيح الأخطاء. فضّل أولًا الدوال العادية أو الأساليب المضمّنة أو اشتقاق given. ولا تلجأ إلى الماكروهات إلا عندما تعجز هذه الخيارات عن التعبير عن الحاجة.
اختبار الماكروهات
اختبر السلوك المُولَّد كما تختبر الكود العادي، واختبر أن المدخلات غير الصالحة تفشل في الترجمة باستخدام أدوات مثل typeCheckErrors من أدوات الاختبار وقت الترجمة.
النظير وقت التشغيل
ينتج ماكرو التحقق وقت الترجمة التأثير نفسه الذي ينتجه فحص وقت التشغيل المستقل هذا، لكن الفشل يحدث أثناء الترجمة بدلًا من وقت التشغيل.
object Main {
def port(n: Int): Int = {
require(n >= 1 && n <= 65535, "invalid port")
n
}
def main(args: Array[String]): Unit = {
println(port(8080)) // 8080
}
}تحقق سريع
ما الميزة الأساسية للتحقق من قيمة حرفية باستخدام ماكرو بدلًا من التحقق منها وقت التشغيل؟
مراجعة
استكشفت حالات استخدام عملية للماكروهات:
assertيلتقط المصدر- التحقق وقت الترجمة باستخدام
errorAndAbort - اشتقاق typeclass عبر
Mirror - التسجيل مع معرفة الموضع
- متى ينبغي تجنب الماكروهات وكيفية اختبارها
لقد أتممت دورة البرمجة الوصفية والماكروهات.
الأسئلة الشائعة
هل درس «Macros عملية» مجاني؟
نعم — نص درس «Macros عملية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Scala for Backend Engineering & Functional Programming، انتقل إلى CoddyKit PRO. تتضمن دورة Scala for Backend Engineering & Functional Programming 4 دروس في المجموع.
ماذا ستتعلم في «Macros عملية»؟
حالات الاستخدام تتمرن على Scala for Backend Engineering & Functional Programming مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Scala for Backend Engineering & Functional Programming؟
لا تُشترط خبرة سابقة. Scala for Backend Engineering & Functional Programming على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «Macros عملية»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Scala for Backend Engineering & Functional Programming هذا؟
نعم. كل درس في Scala for Backend Engineering & Functional Programming يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الدوال Inline
- أساسيات Macros
- الاقتباسات والدمج
- Macros عملية