2009-10-07 31 views
5

我正在玩scala的分布式演员。非常好。模式匹配scala中的零参数函数:通过警告迷惑

我有一个服务器执行传入的函数对象。 例如,客户端有

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

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

和服务器都可以选择这些并与演员这样的代码

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

这一切工作很好地执行它们(这是非常非常酷确实)但我

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

如何清洁此警告了:M通过一条警告消息输出服务器代码迷惑通过scalac

(我在Unit类型之间的区别不太清楚,和()=>Unit类型的零参数的函数。只是想在react匹配task:Unit是免费的预警,但实际上不匹配传入任务)

在Debian上使用Scala 2.7.5,使用Sun的Java6。

回答

10

你真的匹配这样的:

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

由于擦除,单位是不能在运行时可见。 如果你真的不关心的返回类型,你可以在反应块做到这一点:

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

这是补充@Mitch Blevins的答案,因为他的答案会在这种情况下让你通过。

请参阅How do I get around type erasure on Scala? Or, why can’t I get the type parameter of my collections?您可能必须将(Function0[T],Manifest[T])的元组传递给演员。正如您在下面看到的,即使您只是编写matchFunction(foo _),Scala也足够聪明,可以推导出T的类型。

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