2009-10-07 8 views
5

Juego con actores distribuidos de Scala. Muy agradable.Patrón coincidente con funciones de argumento cero en scala: mistificado por advertencia

Tengo un servidor que ejecuta objetos de funciones entrantes. Por ejemplo, el cliente tiene

object Tasks { 
    def foo = {Console.println("I am Foo")}; 
    def bar = {Console.println("I am Bar");} 
} 

// In client actor... 
... 
    server ! Tasks.foo _ 
... 

y el servidor puede recoger estos y ejecutarlos con el código de actor como

react { 
    case task:(()=>Unit) => 
    task() 

Todo esto funciona muy bien (lo cual es muy muy bueno de verdad) pero me estoy desconcertado por una salida de mensaje de advertencia por scalac para el código del servidor:

warning: non variable type-argument Unit in type pattern is unchecked since it is eliminated by erasure 
     case task:(()=>Unit) => 
        ^

Cómo se puede limpiar esta advertencia para arriba?

(estoy bastante claro en la diferencia entre el tipo Unit, y el tipo de funciones sin argumentos ()=>Unit. Sólo tratando de igualar task:Unit en el react está libre de advertencia, pero en realidad no coincide con las tareas entrantes .)

Usando Scala 2.7.5 en Debian, con Sun's Java6.

Respuesta

10

Usted está realmente sean iguales a esta:

case task:Function0[Unit] => task() 

Debido a la cancelación, la Unidad no es visible en tiempo de ejecución. Si realmente no se preocupan por el tipo de retorno, se puede hacer esto en el bloque de reaccionar:

case task:Function0[_] => task() 
3

Ésta es complementar a @Mitch Blevins 's respuesta ya que su respuesta va a obtener a través de este caso.

Ver How do I get around type erasure on Scala? Or, why can’t I get the type parameter of my collections? Probablemente tengas que pasar una tupla de (Function0[T],Manifest[T]) al actor. Como puede ver a continuación, Scala es lo suficientemente inteligente como para deducir el tipo de T, incluso si solo escribe matchFunction(foo _).

scala> def foo = {Console.println("I am Foo")} 
foo: Unit 

scala> import scala.reflect.Manifest 
import scala.reflect.Manifest 

scala> def matchFunction[T](f: Function0[T])(implicit m : Manifest[T]) { 
    | (m,f) match { 
    |  case (om: Manifest[_],of: Function0[_]) => 
    |  if(om <:< m) { 
    |   of.asInstanceOf[Function0[T]]() 
    |  } 
    | } 
    | } 
matchFunction: [T](() => T)(implicit scala.reflect.Manifest[T])Unit 

scala> matchFunction(foo _) 
I am Foo 
Cuestiones relacionadas