ฉันต้องการเขียนโปรแกรมแมโคร Scala ที่ใช้อินสแตนซ์ของคลาสเคสเป็นอาร์กิวเมนต์ ออบเจ็กต์ทั้งหมดที่สามารถส่งผ่านไปยังมาโครจะต้องใช้ลักษณะเครื่องหมายเฉพาะ
ตัวอย่างต่อไปนี้แสดงคุณลักษณะของเครื่องหมายและคลาสกรณีตัวอย่างสองคลาสที่นำไปใช้:
trait Domain
case class Country( id: String, name: String ) extends Domain
case class Town( id: String, longitude: Double, latitude: Double ) extends Domain
ตอนนี้ ฉันต้องการเขียนโค้ดต่อไปนี้โดยใช้มาโครเพื่อหลีกเลี่ยงความหนักหน่วงของการสะท้อนรันไทม์และความไม่ปลอดภัยของเธรด:
object Test extends App {
// instantiate example domain object
val myCountry = Country( "CH", "Switzerland" )
// this is a macro call
logDomain( myCountry )
}
มาโคร logDomain
ถูกนำไปใช้ในโครงการอื่นและมีลักษณะคล้ายกับ:
object Macros {
def logDomain( domain: Domain ): Unit = macro logDomainMacroImpl
def logDomainMacroImpl( c: Context )( domain: c.Expr[Domain] ): c.Expr[Unit] = {
// Here I would like to introspect the argument object but do not know how?
// I would like to generate code that prints out all val's with their values
}
}
วัตถุประสงค์ของมาโครควรเพื่อสร้างโค้ดที่ - ณ รันไทม์ - ส่งออกค่าทั้งหมด (id
และ name
) ของออบเจ็กต์ที่กำหนดและพิมพ์ออกมาดังที่แสดงถัดไป:
id (String) : CH
name (String) : Switzerland
เพื่อให้บรรลุเป้าหมายนี้ ฉันจะต้องตรวจสอบอาร์กิวเมนต์ประเภทที่ส่งแบบไดนามิกและกำหนดสมาชิกของมัน (vals) จากนั้นฉันจะต้องสร้าง AST แทนโค้ดที่สร้างเอาต์พุตบันทึก แมโครควรทำงานได้ไม่ว่าวัตถุเฉพาะที่ใช้ลักษณะเครื่องหมาย "โดเมน" จะถูกส่งผ่านไปยังมาโครหรือไม่
ณ จุดนี้ฉันหลงทาง ฉันจะขอบคุณถ้ามีคนให้จุดเริ่มต้นหรือชี้ให้ฉันดูเอกสารบางอย่าง ฉันค่อนข้างใหม่กับ Scala และไม่พบวิธีแก้ปัญหาในเอกสาร Scala API หรือคู่มือ Macro