相关疑难解决方法(0)

从宏中获取具有匿名类方法的结构类型

假设我们要编写一个定义具有某些类型成员或方法的匿名类的宏,然后创建该类的实例,该类通过这些方法静态地键入为结构类型等.这可以通过2.10中的宏系统实现. 0,类型成员部分非常容易:

object MacroExample extends ReflectionUtils {
  import scala.language.experimental.macros
  import scala.reflect.macros.Context

  def foo(name: String): Any = macro foo_impl
  def foo_impl(c: Context)(name: c.Expr[String]) = {
    import c.universe._

    val Literal(Constant(lit: String)) = name.tree
    val anon = newTypeName(c.fresh)

    c.Expr(Block(
      ClassDef(
        Modifiers(Flag.FINAL), anon, Nil, Template(
          Nil, emptyValDef, List(
            constructor(c.universe),
            TypeDef(Modifiers(), newTypeName(lit), Nil, TypeTree(typeOf[Int]))
          )
        )
      ),
      Apply(Select(New(Ident(anon)), nme.CONSTRUCTOR), Nil)
    ))
  }
}
Run Code Online (Sandbox Code Playgroud)

(提供我方法ReflectionUtils便利特性在哪里constructor.)

这个宏允许我们将匿名类的类型成员的名称指定为字符串文字:

scala> MacroExample.foo("T")
res0: AnyRef{type T = Int} = $1$$1@7da533f6
Run Code Online (Sandbox Code Playgroud)

请注意,它是适当的键入.我们可以确认一切都按预期工作:

scala> implicitly[res0.T =:= Int] …
Run Code Online (Sandbox Code Playgroud)

macros scala structural-typing scala-2.10 scala-macros

182
推荐指数
1
解决办法
8576
查看次数

如何在dotty宏中访问case类的参数列表

我正在尝试在 dotty 中学习元编程。具体编译时间代码生成。我认为通过构建一些东西来学习是一种很好的方法。所以我决定制作一个 CSV 解析器,它将行解析为案例类。我想使用dotty宏来生成解码器

trait Decoder[T]{
  def decode(str:String):Either[ParseError, T]
}

object Decoder {
  inline given stringDec as Decoder[String] = new Decoder[String] {
    override def decode(str: String): Either[ParseError, String] = Right(str)
  }

  inline given intDec as Decoder[Int] = new Decoder[Int] {
    override def decode(str: String): Either[ParseError, Int] =
      str.toIntOption.toRight(ParseError(str, "value is not valid Int"))
  }
  
  inline def forType[T]:Decoder[T] = ${make[T]}

  def make[T:Type](using qctx: QuoteContext):Expr[Decoder[T]] = ???
}
Run Code Online (Sandbox Code Playgroud)

我已经为Int&提供了基本的解码器String,现在我正在寻找def make[T:Type]方法的指导。如何T在此方法中迭代案例类的参数列表?有没有推荐的方法或模式来做到这一点?

reflection scala metaprogramming dotty scala-macros

8
推荐指数
1
解决办法
741
查看次数

Scala 3 中的宏注释

以下是三年多前的Macros: The Plan for Scala 3中的一段话:

例如,我们可以定义一个宏注释 @json,将 JSON 序列化器添加到一种类型中。

知道这在 Scala 3 中如何/是否可行吗?

更一般地说,Scala 3 中有什么可以提供“宏注释”功能吗?以下是宏注释 - Scala 2.13的引用:

与以前版本的宏天堂不同,2.0 中的宏注释在以下意义上是正确的:1) 不仅适用于类和对象,而且适用于任意定义,2)允许扩展类来修改甚至创建伴生对象

scala scala-macros scala-macro-paradise scala-3

7
推荐指数
2
解决办法
1071
查看次数

如何使用宏在 Dotty 中生成一个类?

是否可以在 Dotty, Scala 3 中生成一个带有宏的新类?

兹拉亚

annotations scala metaprogramming dotty scala-macros

6
推荐指数
2
解决办法
729
查看次数

使用 Scala 3 宏重写方法

我正在尝试使用 Scala 3 宏和 TASTY 重写方法。我想重写任何类型的任何方法。现在我从这个简单的案例开始。

我有一个测试基类:

class TestClass {
  def func(s: String) = "base"
}
Run Code Online (Sandbox Code Playgroud)

我想实现这一点,但是通过使用 TASTY,我发现不可能调用new A带有引号和拼接的泛型类型:

'{
    new TestClass() {
       override def func(s: String) = "override"
    }
}.asExprOf[A]
Run Code Online (Sandbox Code Playgroud)

我打印了上述代码的 AST,并且几乎成功地重新创建了它。问题是我无法调用new生成的类 - 我没有找到访问新类的符号或类型的方法。我也尝试Symbol.requiredClass()使用新名称,尽管它返回了一些符号,但在宏扩展期间出现错误,未找到该类。

我的问题是:

  • 是否可以在不显式调用:的new Class {}情况下派生自定义类型?
  • 是否ClassDef.copy注册一个可以帮助创建新实例的新名称?
  • 可以手动调用ClassDef创建类的实例吗?
  • Symbol.requiredClass即使之前没有定义,如何使用返回的符号,因为它会返回某些内容?

我创建的代码:

import scala.quoted.*

object NewClass {

  def newClassImpl[A: Type](e: Expr[A])(using Quotes): Expr[A] = {
    import quotes.reflect.*

    val typeRep = TypeRepr.of[A]

    val ret = typeRep.classSymbol.map(_.tree) match …
Run Code Online (Sandbox Code Playgroud)

scala scala-macros scala-3

5
推荐指数
1
解决办法
876
查看次数

Scala 3 宏中的“tq”等效项

使用 Scala2,我可以实现宏并使用tq准引用语法生成类型,例如:

q"""        
new Foo {
  type Bar = ${tq"(..$params)"}
}
"""
Run Code Online (Sandbox Code Playgroud)

我可以用这种语法做两件事 -

  1. 能够Bar基于params.
  2. 能够将 作为元组传播params

如何使用 Scala 3 实现这一目标?

scala scala-macros scala-quasiquotes scala-3

1
推荐指数
1
解决办法
293
查看次数