![](/img/trans.png)
[英]scala macro generic field of generic class not apply class generic type parameter
[英]Scala 3 macro: generic type from class
我正在使用 Scala 3 宏編程編寫序列化庫。 我想動態生成序列化程序。 因為這是一個庫,所以我不知道編譯過程中序列化器是什么class。 所以我需要一個運行時編譯功能。
代碼:
object CodecMacro {
import scala.quoted.staging.*
given Compiler = Compiler.make(getClass.getClassLoader)
// function 1: entry point: a Class object
def buildSerializer(clazz: Class[_]): Serializer = {
given staging.Compiler = staging.Compiler.make(getClass.getClassLoader)
val fn = (qctx: Quotes) ?=> {
given q: Quotes = qctx
buildSerializerAdapter(clazz)
}
staging.run(fn)
}
// function 2: convert clazz to generic T
// My main question is here
private def buildSerializerAdapter(clazz: Class[_])(using quotes: Quotes): Expr[Serializer] = {
import quotes.reflect.*
val tpe: TypeRepr = TypeRepr.typeConstructorOf(clazz)
val t = tpe.asType
type T = t.Underlying
buildSerializerImpl[T] // error: Missing type parameters for T
}
// function 3: Using a generic T to generate a Serializer
private def buildSerializerImpl[T: Type](using quotes: Quotes): Expr[Serializer] = {
val t = summon[Type[T]]
'{
type T = t.Underlying
new Serializer[T] {
override def serialize(writer: Writer, value: T): Unit = {
// Implemetation, not important
writer.writeString("aaa")
}
}
}
Function 1 是入口點,需要一個 Class object。 Function 3 是最終實現,需要一個泛型類型 T。
Function 2 是從 Class object 轉換為通用類型 T ,這是我的主要問題。
我的解決方案是
Class -> TypeRepr use: TypeRepr.typeConstructorOf(clazz)
TypeRepr -> Type use: TypeRepr.asType
Type -> type T use: Type.Underlying
我以為Type下的type T會解決我的問題,但是編譯器給了我一個錯誤:“Missing type parameters for T”
在 Function 3 中: type T = t.Underlying
value: T
泛型 T 工作正常。
有什么方法可以將 Class object 轉換為通用類型 T?
這是應該完成的方式:
tpe.asType match
case '[t] =>
buildSerializerImpl[t]
這個非常奇怪的調用直接來自asType 的文檔。 這是必要的,因為asType
返回一個Type[?]
,其中Type
接受任何類型類型,但這里我們需要一個具體的類型類型。 如果類型是更高的類型,例如Type[List]
( List
構造函數采用類型參數),則匹配將失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.