scala - 如何在 Scala 3 宏中创建泛型类型的实例?

标签 scala metaprogramming scala-macros scala-3

我正在将一个宏从 Scala 2 移植到 Scala 3。作为其工作的一部分,Scala 2 宏使用默认构造函数创建了一个泛型类型的实例。在 Scala 2 中使用 quasiquote 很容易做到这一点,但我正在努力使用 Scala 3 宏。到目前为止,这是我最好的方法:

import scala.quoted.*

inline def make[A <: AnyRef]: A = ${ makeThat[A] }

private def makeThat[A <: AnyRef : Type](using Quotes): Expr[A] =
  import quotes.reflect.*

  '{ new A().asInstanceOf[A] }
没有 .asInstanceOf[A] ,编译器发出错误信息:
[error] -- [E007] Type Mismatch Error: ...
[error] 17 |  '{ new A() }
[error]    |     ^^^^^^^
[error]    |Found:    Object
[error]    |Required: A
[error]    |
[error]    |where:    A is a type in method makeThat with bounds <: AnyRef
[error] one error found
有没有在运行时没有向下转型的更好的解决方案?
编辑:从 Scala 3.0.1 开始,这甚至不再编译。

最佳答案

您可以使用较低级别的反射 API 创建正确的树。

import scala.quoted.*

inline def make[A <: AnyRef]: A = ${ makeThat[A] }

def makeThat[A <: AnyRef : Type](using Quotes): Expr[A] =
  import quotes.reflect.*

  TypeRepr.of[A].classSymbol.map( sym =>
    Apply(Select(New(TypeTree.of[A]), sym.primaryConstructor), Nil).asExprOf[A]
  )
  .getOrElse(???) // not a class, so can't instantiate
尽管您应该检查一下您的构造函数是否没有参数。

关于scala - 如何在 Scala 3 宏中创建泛型类型的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67738828/

相关文章:

c++ - 在 C++ 中实现(类型化的)K 组合器

c++ - 在 C++ 中使用带有模板方法的模板类

scala - 从 SBT 项目中的宏读取资源

c++ - 没有 constexpr 内容的 Constexpr 循环

scala - 在 REPL 中将代码扩展为原始 AST Scala 3

scala - 无法在宏生成的类中访问方法

java - SimpleDateFormat 用于类似 RFC 的时间戳?

scala - Spark : Programmatically creating dataframe schema in scala

scala - 在 Spark-shell 中使用库

Scala 解析器组合器将字符列表转换为字符串