2014-11-06 8 views
8

Che cosa significa questo avviso significa:avvertimento circa l'accesso riflettente di membro di tipo strutturale a Scala

accesso riflettente di tipo metodo membro getMap strutturale dovrebbe essere abilitata

L'avviso include un riferimento alla Scala documenti ma non capisco come il mio codice sia correlato alla spiegazione. (In particolare la spiegazione menziona riflessione ... come è il mio codice utilizzando la riflessione?)

ho questo: (Scala 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 

Questo genera l'avviso di seguito:

[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]      ^

risposta

13

Penso che quello che sta succedendo è che gli oggetti new { ... } sono strutturalmente digitati, che richiedono una riflessione da implementare.

Il motivo sottostante è che la tipizzazione strutturale di Scala consente di trattare gli oggetti come se fossero istanze di molti tipi in base ai metodi effettivamente utilizzati (come la digitazione anatra). La JVM consente esattamente un tipo, quindi i metodi che non fanno parte del tipo sottostante dell'oggetto devono essere accessibili tramite qualcosa di diverso da una normale chiamata di metodo virtuale. Il meccanismo utilizzato in questo caso è la riflessione.

Quando il compilatore scala vede un'invocazione di un metodo che viene chiamato su un oggetto strutturalmente digitata (Modulo alcune ottimizzazioni) trasla una chiamata metodo come:

a.f(b, c) 

a

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

Esempio preso da the place where the technique was described.

Il team di Scala ha deciso di applicare una politica di attivazione per funzionalità avanzate che tutti potrebbero non utilizzare. reflectiveCalls sembra essere uno di questi come documentato in questo SIP

Problemi correlati