Несоответствие типов при использовании allCatch opt - PullRequest
1 голос
/ 16 июня 2011

Чтобы избежать исключений Java, я использую класс обработки исключений Scala.

Однако при компиляции следующего фрагмента:

 import scala.util.control.Exception._

 val cls = classManifest[T].erasure

 // Invoke special constructor if it's available. Otherwise use default constructor.
 allCatch opt cls.getConstructor(classOf[Project]) match {
   case Some(con) =>
     con.newInstance(project) // use constructor with one Project param
   case None =>
     cls.newInstance // just use default constructor
 };

я получаю следующую ошибку:

 error: type mismatch;
    [scalac]  found   : java.lang.reflect.Constructor[_]
    [scalac]  required: java.lang.reflect.Constructor[_$1(in method init)] where
              type _$1(in method init)
    [scalac]     allCatch opt cls.getConstructor(classOf[Project]) match {
    [scalac]                                    ^
    [scalac] one error found

Что здесь происходит и как я могу это исправить?

Ответы [ 3 ]

2 голосов
/ 17 июня 2011

У меня нет объяснения, но есть более короткий пример, который, я надеюсь, точно определит место возникновения проблемы.Я думаю, что это вообще не связано ни с исключениями, ни с отражением.Является ли это поведение загадочным, но правильным следствием спецификации или ошибкой, я понятия не имею.

val untypedList : List[_] = List("a", "b")
val typedList : List[String] = List("a", "b") 
def uselessByName[A](a: => A) = a
def uselessByValue[A](a: A) = a

uselessByName(untypedList) завершается с той же ошибкой, что и ваш код.Других комбинаций нет.Таким образом, комбинация метода с универсальным аргументом call-by-name вызывается с помощью универсального параметра с экзистенциальным типом.

uselessByName[List[_]](untypedList) работает, так что я думаю, что если вы вызовете явно opt[Constructor[_]], это тоже может сработать.

0 голосов
/ 16 июня 2011

Схема вывода типов путается с доступными типами, в частности с типом cls.Если мы напишем общий код:

def clser[A](cls: Class[A]) = allCatch opt cls.getConstructor(classOf[Project])

, тогда все будет отлично.Но вы, вероятно, делаете что-то другое - я не могу сказать, что, потому что вы не предоставили код - и это приводит к несоответствию между ожидаемым и фактическим типами.

0 голосов
/ 16 июня 2011

Мое настоящее решение - явное приведение конструктора.

cls.getConstructor(classOf[Project]) становится cls.getConstructor(classOf[Project]).asInstanceOf[Constructor[Project]].

Я все еще задаюсь вопросом о фактической ошибке и о том, есть ли лучшие способы ее устранения - поэтому я собираюсь оставить это открытым.

...