พื้นฐานมาโคร
โค้ดขณะคอมไพล์
พื้นฐานมาโคร เป็นบทเรียน Scala for Backend Engineering & Functional Programming ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Scala for Backend Engineering & Functional Programming และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
มาโครคืออะไร
มาโครคือโค้ดที่ทำงานในเวลาคอมไพล์เพื่อสร้างโค้ดอื่น มาโครของ Scala 3 ช่วยให้คุณตรวจสอบอาร์กิวเมนต์ สร้างนิพจน์ และแทรกนิพจน์เหล่านั้นลงในโปรแกรมก่อนการคอมไพล์
รูปแบบ Inline + มาโคร
มาโครถูกเรียกใช้จาก inline def ซึ่งส่งต่องานให้เมธอดที่กำกับด้วย ${ ... } def แบบ Inline เป็น API สาธารณะ ส่วนการทำงานของมาโครจะเกิดขึ้นในคอมไพเลอร์
import scala.quoted.*
inline def power(x: Double, inline n: Int): Double =
${ powerImpl('x, 'n) }บริบท Quotes
การนำมาโครไปใช้งานทุกครั้งต้องรับบริบท Quotes โดยปริยาย บริบทนี้ให้สิทธิ์เข้าถึง API การสะท้อน และความสามารถในการสร้างและแทรกนิพจน์
import scala.quoted.*
def powerImpl(x: Expr[Double], n: Expr[Int])(using Quotes): Expr[Double] =
???Expr[T]
Expr[T] แทนนิพจน์ที่มีชนิดกำกับชนิด T ในรูปข้อมูลเวลาคอมไพล์ มาโครจะรับและส่งคืนค่า Expr
การยกค่าขึ้นเป็น Expr
Expr(value) ยกค่าขณะทำงานที่คำนวณในมาโครขึ้นเป็นนิพจน์เพื่อแทรกกลับเข้าไป วิธีนี้ใช้ได้กับทุกชนิดที่มีอินสแตนซ์ ToExpr
import scala.quoted.*
def constImpl(using Quotes): Expr[Int] = Expr(42)การดึงอาร์กิวเมนต์ค่าคงที่
n.value (หรือ n.valueOrAbort) ดึงค่าคงที่ที่อยู่เบื้องหลัง Expr เมื่ออาร์กิวเมนต์เป็นที่ทราบแน่ชัดแบบสถิต ทำให้มาโครสามารถเลือกแขนงการทำงานตามค่านั้นได้
import scala.quoted.*
def powerImpl(x: Expr[Double], n: Expr[Int])(using Quotes): Expr[Double] = {
val exp = n.valueOrAbort
??? // build x*x*...*x exp times
}การรายงานข้อผิดพลาด
ใช้ quotes.reflect.report.errorAndAbort เพื่อส่งข้อผิดพลาดในการคอมไพล์พร้อมข้อความและตำแหน่ง เมื่อเงื่อนไขเบื้องต้นของมาโครไม่เป็นไปตามที่กำหนด
import scala.quoted.*
def check(n: Expr[Int])(using q: Quotes): Expr[Int] = {
import q.reflect.*
val v = n.valueOrAbort
if (v < 0) report.errorAndAbort("must be >= 0")
Expr(v)
}มาโครอยู่ที่ใด
การนำมาโครไปใช้งานต้องคอมไพล์ก่อนโค้ดที่เรียกใช้ โดยทั่วไปจะอยู่ในไฟล์หรือโมดูลแยกต่างหาก คอมไพเลอร์จะเรียกใช้มาโครเหล่านั้นขณะคอมไพล์โค้ดที่เรียกใช้
กรณีการใช้งานทั่วไป
มาโครช่วยขับเคลื่อน:
- การสร้างอนุพันธ์ของไทป์คลาส (ตัวเข้ารหัส JSON เป็นต้น)
- การตรวจสอบความถูกต้องในเวลาคอมไพล์ (นิพจน์ทั่วไป, SQL)
- การบันทึกล็อกที่เก็บตำแหน่งต้นฉบับ
- นามธรรมที่ไม่มีค่าใช้จ่ายเพิ่มเติม
ความปลอดภัยและสุขอนามัย
มาโคร Scala 3 มีคุณสมบัติปลอดการปะปนของชื่อ: ตัวระบุที่สร้างขึ้นจะไม่จับตัวแปรของผู้ใช้โดยไม่ได้ตั้งใจ และระบบชนิดจะตรวจสอบโค้ดที่สร้างขึ้น จึงป้องกันข้อผิดพลาดคลาสสิกของมาโครได้หลายประการ
สิ่งเทียบเท่าขณะทำงาน
มาโครที่คำนวณการยกกำลังในเวลาคอมไพล์จะให้ผลลัพธ์เดียวกับรุ่นที่ทำงานได้ในตัวเองขณะทำงานนี้ แต่คอมไพเลอร์จะฝังการคูณไว้ล่วงหน้า
object Main {
def power(x: Double, n: Int): Double =
if (n == 0) 1.0 else x * power(x, n - 1)
def main(args: Array[String]): Unit = {
println(power(2.0, 3)) // 8.0
}
}ตรวจสอบอย่างรวดเร็ว
ชนิดใดใช้แทนนิพจน์ที่มีชนิดกำกับในเวลาคอมไพล์ ซึ่งมาโครรับและส่งคืน
สรุปทบทวน
คุณได้เรียนรู้พื้นฐานมาโคร:
- มาโครทำงานในเวลาคอมไพล์ผ่านรูปแบบ
inline def ... ${ } - บริบท
QuotesและExpr[T] - การยกค่าด้วย
Expr(...)และการดึงค่าด้วย.value - การรายงานข้อผิดพลาดและสุขอนามัย
ถัดไป: quotes และการแทรก
คำถามที่พบบ่อย
บทเรียน “พื้นฐานมาโคร” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “พื้นฐานมาโคร” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Scala for Backend Engineering & Functional Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “พื้นฐานมาโคร”
โค้ดขณะคอมไพล์ คุณปฏิบัติ Scala for Backend Engineering & Functional Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Scala for Backend Engineering & Functional Programming หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Scala for Backend Engineering & Functional Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “พื้นฐานมาโคร” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Scala for Backend Engineering & Functional Programming นี้ได้ไหม
ได้ บทเรียน Scala for Backend Engineering & Functional Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ