2014-09-04 4 views
2

Je suis nouveau sur scala et je rencontre un problème lors de l'appel d'une fonction "générique" dans la bibliothèque java NIO (à partir de scala 2.10.x). La réduction du code à un test simple:Appel de la fonction générique java à partir de scala

import java.net._ 
import java.nio.channels.{MembershipKey, DatagramChannel} 

object Test { 
    val channel = DatagramChannel.open(StandardProtocolFamily.INET) 
    .setOption(StandardSocketOptions.SO_REUSEADDR, true) 
    ... 
} 

Il en résulte:

Error:(40, 48) type mismatch; 
found : java.net.SocketOption[Boolean] 
required: java.net.SocketOption[Any] 
Note: Boolean <: Any, but Java-defined trait SocketOption is invariant in type T. 
You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10) 
    channel.setOption(StandardSocketOptions.SO_REUSEADDR, true) 
             ^

Je suppose qu'il ya un moyen de résoudre ce sans avoir recours à l'écriture d'un emballage en java. Ont essayé de refondre de diverses façons sans succès.

Question: comment résoudre ce problème?

Répondre

5

Méthode setOption est polymorphe

setOption[T](name: SocketOption[T], value: T): DatagramChannel 

donc lors de l'appel

setOption(StandardSocketOptions.SO_REUSEADDR, true) 

scala voir que les types d'arguments sont légèrement différents

StandardSocketOptions.SO_REUSEADDR: SocketOption[java.lang.Boolean] 
true: scala.Boolean 

et compilateur essaie de réduire T au plus type commun entre java.lang.Boolean <: AnyRef et scala.Boolean <: AnyVal qui est Any

pour résoudre ce problème, vous devez fournir soit le type explicite pour setOption

setOption[java.lang.Boolean](StandardSocketOptions.SO_REUSEADDR, true) 

ou utiliser le type ascription (alors T sera correctement inféré)

setOption(StandardSocketOptions.SO_REUSEADDR, true: java.lang.Boolean) 
Questions connexes