2014-11-06 84 views
8

这是什么警告结构类型构件的反射访问意味着:警告约Scala中

结构型部件的方法的GetMap的反射访问应启用

该警告包括到阶参考文档,但我不明白我的代码如何与解释相关。 (具体的解释中提到反射...如何使用我的代码反映?)

我有这样的:(斯卡拉2.11.2)

object getMap { 
    implicit def fromOptionToConvertedVal[T](o:Option[T]) = new { 
     def getMap[R] (doWithSomeVal:(T) => R) = new { 
      def orElse(handleNone: => R) = o match { 
       case Some(value) => doWithSomeVal(value) 
       case None => handleNone 
      } 
     } 
    } 
} 

import getMap._ 
val i:Option[Int] = Some(5) 
val x = i getMap (_*2) orElse 1 

这会生成以下警告:

[warn] /Users/Greg/git/Favorites-Demo/src/main/scala/com/rs/server/ThriftServer.scala:34: reflective access of structural type member method getMap should be enabled 
[warn] by making the implicit value scala.language.reflectiveCalls visible. 
[warn] This can be achieved by adding the import clause 'import scala.language.reflectiveCalls' 
[warn] or by setting the compiler option -language:reflectiveCalls. 
[warn] See the Scala docs for value scala.language.reflectiveCalls for a discussion 
[warn] why the feature should be explicitly enabled. 
[warn] val x = i getMap (_*2) orElse 1 
[warn]   ^
[warn] /Users/Greg/git/Favorites-Demo/src/main/scala/com/rs/server/ThriftServer.scala:34: reflective access of structural type member method orElse should be enabled 
[warn] by making the implicit value scala.language.reflectiveCalls visible. 
[warn] val x = i getMap (_*2) orElse 1 
[warn]      ^

回答

13

我认为发生的事情是new { ... }对象是结构类型,需要反射来实现。

潜在的原因是,Scala结构类型允许将对象视为它们是实际拥有的方法(如鸭子打字)的许多类型的实例。 JVM只允许一种类型,所以不属于对象底层类型的方法必须通过非正常的虚拟方法调用来访问。在这种情况下使用的机制是反思。

当阶编译器看到一个该被呼叫结构上类型化的对象时,它(模一些优化)对方法的调用转换等的方法调用:

a.f(b, c) 

a.getClass 
    .getMethod("f", Array(classOf[B], classOf[C])) 
    .invoke(a, Array(b, c)) 

实施例取自the place where the technique was described

斯卡拉团队决定强制实施一项适用于大家可能不会使用的高级功能的选择策略。 reflectiveCalls碰巧是其中之一SIP