微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

在 scala 2 中已知宏是严格本地的,并且只在定义类时执行一次。这一特性在与抽象类型结合时显得尤为薄弱,因为将抽象类型转换为具体类型的过程通常会绕过宏并使用其自身的原始规则。

以下测试代码中展示了一个与直觉相反的结果的简单示例:

  trait BB {

    def ttag = implicitly[TypeTag[this.type]]
  }

  case class AA() extends BB

  it("can TypeTag") {

    val kk = AA()

    TypeViz(kk.ttag).peek // this function visualise the full type tree of the type tag
  }

如果执行,kk的类型是:

-+ BB.this.type
 !-+ InfoCTSpec.this.BB
   !-+ Object
     !-- Any

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

我想编写/使用语言扩展,例如使 kk.this.type 成为 AA 的子类型,而不引入运行时开销和范围外上下文对象(因此,无隐含)。我怎样才能以最少的黑客攻击做到这一点?我对编译器扩展和宏等非常核心的解决方案持开放态度,但显然更喜欢可以顺利转移到 Scala 3/dotty 的优雅变通方法

附言看起来点点滴滴的“内联/编译时”功能已经部分实现了我的设想。这是正确的印象吗?

解决方法

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

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

When doing implicit resolution with type parameters,why does val placement matter?

不引入运行时开销和范围外上下文对象(因此,无隐含)。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。