【发布时间】:2022-11-22 03:41:15
【问题描述】:
用例需要在运行时比较两个类型参数的实际类型。使用TypeTag 可能很容易做到这一点,但它在 scala-3 中已被弃用。
因此,我尝试使用TypeTest,但它需要存在该类型的实例,而我没有。
所以,我实现了TypeId,我自己的TypeTag版本。它的方式更加有限和简单。它仅支持类型比较,并且仅当每个涉及的类型都存在 TypeId 的单个实例时才有效。
import scala.collection.{mutable, immutable}
object TypeId {
private var idSequencer: Int = 0
private val typeIds: mutable.HashMap[Int, TypeId[?]] = mutable.HashMap.empty
private def registerNew[A](tm: TypeId[A]): Int = this.synchronized {
idSequencer += 1
typeIds.put(idSequencer, tm)
idSequencer
}
def knownTypeIds: immutable.HashMap[Int, TypeId[?]] = this.synchronized(immutable.HashMap.from(typeIds))
}
trait TypeId[A] {
val id: Int = registerNew(this)
def equalsTo(that: TypeId[?]): Boolean = this.id == that.id
}
如您所见,它要求同步是线程安全的,这很不方便; knownTypeIds 的值容易受到竞争条件的影响。
我想知道是否可以使用宏在编译时创建唯一 ID。我想为此我需要某种编译时全局变量来实现音序器。 scala-3 宏是否支持编译时全局变量或实现我的目标的替代方法?
编辑:问完我的问题几分钟后,我想出了一个非常简单的方法来实现我的目标,方法是将标识符设为带有类型扩展名的字符串。这样的名称可以很容易地在宏中生成。 但是,我想知道 scala-3 宏是否支持编译时全局变量。
【问题讨论】:
标签: scala scala-macros scala-3