使用结构类型的REPL警告

时间:2017-11-28 19:58:24

标签: scala

为什么REPL会对使用结构类型发出警告?结构类型是否不安全?

scala> def test(st: { def close():Unit})
     | = st.close()
<console>:12: warning: reflective access of structural type member method close should be enabled
by making the implicit value scala.language.reflectiveCalls visible.
This can be achieved by adding the import clause 'import scala.language.reflectiveCalls'
or by setting the compiler option -language:reflectiveCalls.
See the Scaladoc for value scala.language.reflectiveCalls for a discussion
why the feature should be explicitly enabled.
       = st.close()
            ^
test: (st: AnyRef{def close(): Unit})Unit

2 个答案:

答案 0 :(得分:2)

警告建议查看Scaladoc页面,其中显示

  

为什么要控制它?所有平台都没有反射功能。流行   ProGuard等工具在处理它时遇到了问题。即使在哪里   反射是可用的,反射性调度可以导致令人惊讶   性能下降。

Source

要使警告消失,只需将import scala.language.reflectiveCalls添加到文件顶部,即表示您确实打算使用此语言功能。

答案 1 :(得分:1)

我想提出另一种观点,而不是Silvio Mayolo的回答。

从根本上说,重要的是Scala被编译成JVM而不是某些Scala特定的目标平台。这意味着目标平台(JVM)不支持Scala中存在的许多功能,并且它们必须以某种方式由编译器模拟。其中一个特征是结构类型,它是使用反射实现的。使用反射引入了Silvio的答案中提到的一系列潜在问题。因此,编译器开发人员希望确保您了解可能的缺点,并且仍然希望通过强制执行显式导入,编译器配置或警告来使用此功能。

至于您的情况下的替代方案,您可以使用java.lang.AutoCloseable而不是结构类型,它可能会涵盖您的大多数情况。

另一种方法是使用implicit参数和type class想法:

trait CloseableTC[A] {
  def close(closeable: A): Unit
}


object CloseableTC {
  implicit val javaCloseable: CloseableTC[java.lang.AutoCloseable] = new CloseableTC[java.lang.AutoCloseable] {
    override def close(closeable: AutoCloseable): Unit = closeable.close()
  }

  // add here more implicits for other classes with .close()
}

def testTC[A](a: A)(implicit closeableTC: CloseableTC[A]) = closeableTC.close(a)

import CloseableTC._
相关问题