2014-11-06 92 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