模式匹配scala中的零参数函数:通过警告神秘化

时间:2009-10-07 23:03:44

标签: scala functional-programming pattern-matching

我正在玩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()

这一切都很好用(确实非常非常酷)但我对scalac输出的服务器代码的警告消息感到困惑:

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

如何清除此警告?

(我很清楚Unit类型和()=>Unit类型的零参数函数之间的区别。只是尝试匹配task:Unit react无警告,但实际上与传入的任务不匹配。)

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

2 个答案:

答案 0 :(得分:10)

你真的很喜欢这个:

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

由于擦除,Unit在运行时不可见。 如果您真的不关心返回类型,可以在react块中执行此操作:

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

答案 1 :(得分: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])的元组传递给actor。正如您在下面所看到的,即使您只是写T,Scala也足够聪明地推断出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