在scala 2中,可以使用宏或任何语言特性重写所有子类中的抽象类型具体化机制吗?scala 3怎么样?

在scala 2中,可以使用宏或任何语言特性重写所有子类中的抽象类型具体化机制吗?scala 3怎么样?,scala,scala-macros,scala-compiler,scala-3,scala-2.13,Scala,Scala Macros,Scala Compiler,Scala 3,Scala 2.13,在scala 2中,宏是严格本地的,并且在定义类时只执行一次。当与抽象类型组合时,此功能似乎特别弱,因为将抽象类型转换为具体类型的过程通常会绕过宏并使用自己的基本规则 下面的测试代码中有一个简单的例子,演示了一个反直觉的结果: trait-BB{ def ttag=隐式[TypeTag[this.type]] } case类AA()扩展了BB 它(“CanTypeTag”){ val kk=AA() TypeViz(kk.ttag).peek//此函数可视化类型标记的完整类型树 } 如果执行,

在scala 2中,宏是严格本地的,并且在定义类时只执行一次。当与抽象类型组合时,此功能似乎特别弱,因为将抽象类型转换为具体类型的过程通常会绕过宏并使用自己的基本规则

下面的测试代码中有一个简单的例子,演示了一个反直觉的结果:

trait-BB{
def ttag=隐式[TypeTag[this.type]]
}
case类AA()扩展了BB
它(“CanTypeTag”){
val kk=AA()
TypeViz(kk.ttag).peek//此函数可视化类型标记的完整类型树
}
如果执行,kk的类型为:

-+ BB.this.type
 !-+ InfoCTSpec.this.BB
   !-+ Object
     !-- Any
糟糕的是,AA类型被完全忽略,因为
隐式[TypeTag[this.type]]
由内置的宏隐式支持,该宏隐式仅在定义BB时执行一次,而在定义AA并具体化实际的
kk.this.type
时不执行。我发现它非常笨拙,并且由于运行时类型擦除,容易导致其他一些功能(例如模式匹配、类型lambda)降级

我想编写/使用语言扩展,例如使
TypeTag[this.type]
成为AA的子类型,而不引入运行时开销和范围外上下文对象(因此,没有隐式)。我怎样才能用最少的黑客攻击做到这一点?我对编译器扩展和宏之类的硬核解决方案持开放态度,但显然更喜欢优雅的解决方案,可以顺利过渡到scala 3/dotty


另外,dotty的“inline/compiletime”功能似乎部分实现了我的设想。这是正确的印象吗?

您可以自由编写宏和编译器插件,但推迟从定义站点到调用站点的隐式解析的传统机制是用隐式参数隐式替换

trait BB {
  def ttag(implicit tt: TypeTag[this.type]) = tt
}

不引入运行时开销&范围外上下文对象(因此,没有隐式)


不清楚你为什么要避免它。隐式在编译时解析。如果用宏或编译器插件替换它,那么无论如何,你都会在编译时手动解决隐式问题。

你想解决的元问题是什么?哦,很简单:我使用了单例操作(类似于dotty中的compiletime操作),然后我发现与dotty不同,它保留了所有类型构造函数,它充满了复杂的类型别名,因此ops之后的结束类型超过了java字符串的65535字节限制。“Scala 3怎么样?”部分可能是一个新问题,因为相同的方法可能不适用于Scala 2和Scala 3。是的,它们应该有完全不同的机制。我提到scala 3只是为了看看它是否正确trivial@tribbloid在哪里可以获得
类型的代码,即peek