0Pricing
Scala for Backend Engineering & Functional Programming · บทเรียน

พื้นฐานมาโคร

โค้ดขณะคอมไพล์

พื้นฐานมาโคร เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. เมธอด Inline
  2. พื้นฐานมาโคร
  3. เครื่องหมายอัญประกาศและการแทรกโค้ด
  4. มาโครเชิงปฏิบัติ
← กลับไปที่ Scala for Backend Engineering & Functional Programming