甚至无法尝试在Scala中加载类

时间:2012-12-14 01:20:53

标签: scala types

这是你去的那个时代之一,你是什么意思,它不编译?

这不是一个修辞问题:什么是最短或惯用的解决方案?对于奖励积分,为什么有必要?

scala> import scala.util.Try
import scala.util.Try

scala> Try { getClass.getClassLoader loadClass "scala.util.Try" }

我希望这不会让游戏消失,但这里有消息:

<console>:9: error: type mismatch;
 found   : Class[_]
 required: Class[?0(in value res0)] where type ?0(in value res0)
Note: Any >: ?0, but Java-defined class Class is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: ?0`. (SLS 3.2.10)
              Try { getClass.getClassLoader loadClass "scala.util.Try" }

通过“调查”,它们是指基础研究,还是只应用文献中已有的技术?

我还在等待这样的错误信息:“留下作为读者的练习。”

更新

这是Scala 2.10的练习。

像往常一样,所有好事都会等到那些等待的人:

apm@mara:~/tmp$ skala
Welcome to Scala version 2.11.0-20130622-103744-990c2b024a (OpenJDK 64-Bit Server VM, Java 1.7.0_21).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.language.existentials
import scala.language.existentials

scala> import scala.util.Try
import scala.util.Try

scala> Try { getClass.getClassLoader loadClass "scala.util.Try" }
res0: scala.util.Try[Class[?0]] forSome { type ?0 } = Success(class scala.util.Try)

2 个答案:

答案 0 :(得分:1)

这肯定是一个重复的问题。也许有人可以指出它,或者确切地说类型推断是如何不做这里自然产生的。

有人给MacIver on existential types一个有用的链接留下了答案(似乎已经消失了吗?)。可能,我还需要MacGyver的帮助。

以下是我在去论坛的路上尝试过的一些变种。

package classy
import scala.util._

class Foo

object Test {

  /* DNC
  def loadTry(n: String, loader: ClassLoader) = Try { loader loadClass n }
  def loadTry(n: String, loader: ClassLoader): Try[Class[_]] = Try { loader loadClass n }
  */

  def main(args: Array[String]) {
    val cl = getClass.getClassLoader
    println(loadTry("classy.Foo", cl))
    println(loadTry("classy.Bar", cl))

    println(cl loadClass "classy.Foo")
    println(loadOpt("classy.Foo", cl))
    println(loadTryAgain("classy.Foo", cl))
    println(loadTryYetAgain("classy.Foo", cl))
  }

  def loadOpt(n: String, loader: ClassLoader): Option[Class[_]] =
    try Some(loader loadClass n) catch {
      case _: Exception => None
    }
  def loadTryAgain(n: String, loader: ClassLoader): Try[Class[_]] = {
    val res: Option[Class[_]] = try Some(loader loadClass n) catch {
      case _: Exception => None
    }
    res match {
      case None    =>
        Failure(new RuntimeException(s"Warning: class not found: ${n})"))
      case Some(x) =>
        Success(x)
    }
  }
  def loadTryYetAgain(n: String, loader: ClassLoader): Try[Class[_]] = {
    val res = try loader loadClass n catch {
      case _: Exception => null
    }
    res match {
      case null =>
        Failure(new RuntimeException(s"Warning: class not found: ${n})"))
      case x    =>
        Success(x)
    }
  }
  def loadTry(n: String, loader: ClassLoader) =
    Try[Class[_]] {
      loader loadClass n
    } recoverWith {
      case e: Exception =>
        Failure(new RuntimeException(s"Warning: class not found: ${n} (${e.getMessage})"))
    }
}

答案 1 :(得分:1)

Try正在造成它。对我来说,scala 2.10.0:

scala> import scala.util.Try
scala> val typeName = "scala.util.Try"    

错误:

scala> Try(Class.forName(typeName))
<console>:10: error: type mismatch;
 found   : Class[_]
 required: Class[?0(in value res1)] where type ?0(in value res1)
Note: Any >: ?0, but Java-defined class Class is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: ?0`. (SLS 3.2.10)
              Try(Class.forName(typeName))
                               ^

没有错误:

scala> Try[Class[_]](Class.forName(typeName))
res2: scala.util.Try[Class[_]] = Success(class scala.util.Try)

catching也有同样的问题:

scala> import scala.util.control.Exception._

scala> catching(classOf[Throwable]) opt Class.forName(typeName)
<console>:13: error: type mismatch;
 found   : Class[_]
 required: Class[?0(in value res4)] where type ?0(in value res4)
Note: Any >: ?0, but Java-defined class Class is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: ?0`. (SLS 3.2.10)
              catching(classOf[Throwable]) opt Class.forName(typeName)