Reputation: 16723
Why REPL gives warning on using structural types? Are structural types unsafe to use?
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
Upvotes: 0
Views: 144
Reputation: 23788
I would like to put another point of view than Silvio Mayolo's answer.
Fundamentally the important thing here is that Scala is compiled into a JVM rather than some Scala-specific target platform. This means that many features that exist in Scala are not supported out of the box by the target platform (JVM) and they have to be somehow simulated by the compiler. One of such features is structural types and it is implemented using reflection. And using reflection introduces a bunch of potential issues that are mentioned in Silvio's answer. Thus compiler developers want to make sure that you understand possible drawbacks and still want to use this feature by enforcing either explicit import, compiler configuration or warning.
As for alternatives in your case you may use java.lang.AutoCloseable
instead of your structural type and it will probably cover most of your cases.
Another alternative is to use implicit
parameter and type class idea:
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._
Upvotes: 1
Reputation: 70277
The warning suggests viewing the Scaladoc page, which says
Why control it? Reflection is not available on all platforms. Popular tools such as ProGuard have problems dealing with it. Even where reflection is available, reflective dispatch can lead to surprising performance degradations.
To make the warning go away, simply add import scala.language.reflectiveCalls
to the top of your file to indicate that, yes, you do in fact intend to use this language feature.
Upvotes: 2