Сопоставление с образцом функций без аргументов в scala: мистифицировано предупреждением - PullRequest
5 голосов
/ 08 октября 2009

Я играю с распределенными актерами Скалы. Очень мило.

У меня есть сервер, который выполняет объекты входящих функций. Например, клиент имеет

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 не содержит предупреждений, но на самом деле не соответствует входящим задачам.)

Использование Scala 2.7.5 в Debian с Sun Java6.

Ответы [ 2 ]

10 голосов
/ 08 октября 2009

Вы действительно соответствуете:

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

Из-за стирания устройство не видно во время выполнения. Если вы действительно не заботитесь о типе возвращаемого значения, вы можете сделать это в блоке реакции:

case task:Function0[_] => task()
3 голосов
/ 08 октября 2009

Это дополнение к ответу @ Mitch Blevins , поскольку его ответ поможет вам в этом случае.

См. Как обойти стирание типов в Scala? Или, почему я не могу получить параметр типа своих коллекций? Возможно, вам придется передать актеру * кортеж (Function0[T],Manifest[T]). Как вы можете видеть ниже, Scala достаточно умен, чтобы вывести тип T, даже если вы просто напишите 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
...