简体   繁体   English

Dotty/Scala 3 中的结构类型编译失败?

[英]Structural types in Dotty/Scala 3 compiled failed?

I tested the following code of structural type:我测试了以下结构类型的代码:

trait Data

object Main
{
  def main(args: Array[String]): Unit =
  {
    val data = new Data {
      val value: Int = 1
    }

    println(data.value)
  }
}

It compiled successfully in Scala 2.13.2 but failed in Dotty/Scala3.它在 Scala 2.13.2 中成功编译,但在 Dotty/Scala3 中失败。 How to use structural types in Dotty/Scala3?如何在 Dotty/Scala3 中使用结构类型? Thanks!谢谢!

From what I see:据我所见:

  • inference changed, so you have to refine type explicitly:推理改变了,所以你必须明确地细化类型:
     val data: Data { val value: Int } = new Data { val value: Int = 1 }
    You can see it clearly when you run dotr and check what is the inferred type当你运行dotr并检查推断的类型是什么时,你可以清楚地看到它
  • to make use of refinement you have to let compiler know that you don't mind reflection要使用细化,您必须让编译器知道您不介意反射
    import reflect.Selectable.reflectiveSelectable

Putting it together:把它放在一起:

import reflect.Selectable.reflectiveSelectable

trait Data

object Main
{
  def main(args: Array[String]): Unit =
  {
    val data: Data { val value: Int } = new Data {
      val value: Int = 1
    }

    println(data.value)
  }
}

I guess the reason why you have to do this is because many times when one didn't want to have refinement, one had it (eg test all test fixtures new Fixture {... } were refined types unnecessarily).我想你必须这样做的原因是因为很多时候一个人不想进行细化,一个人拥有它(例如测试所有测试夹具new Fixture {... }是不必要的细化类型)。 The other is that refinements use reflection when accessing refinements (in Scala 2) which causes performance penalty - so it is something we should do consciously and not accidentally.另一个是在访问细化时(在 Scala 2 中)细化使用反射,这会导致性能损失——所以这是我们应该有意识地而不是偶然地做的事情。

In Scala 3, structural types are implemented using dynamics , which require mixing in Selectable trait.在 Scala 3 中,结构类型是使用dynamics实现的,这需要混合Selectable trait。 Because of that you would have to import scala.reflect.Selectable.reflectiveSelectable implicit conversion to allow it to work like in Scala 2. If you want to make things work like before you can add import reflect.Selectable.{ given _ } as suggested by @Dmytro Mitin (and add reflection back).因此,您必须导入scala.reflect.Selectable.reflectiveSelectable隐式转换以使其像 Scala 2 中一样工作。如果您想让事情像之前那样工作,您可以添加import reflect.Selectable.{ given _ } @Dmytro Mitin(并添加反射)。

You can try to do it globally eg by exporting it in your package, but it you would do it on your own risk.您可以尝试在全球范围内执行此操作,例如通过将其导出到您的 package 中,但这样做需要您自担风险。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM