我昨天开始学习Scala,所以我对它很陌生.在学习新语言时,我喜欢做的一件事是尝试创建一个微TDD库.
这是我到目前为止所得到的:
def assert(condition: Boolean, message: String) {
if(!condition){ throw new AssertionError(message) }
}
def assertThrows[E](f: => Unit) {
try {
f
} catch {
case e: E => { return }
case _: Exception => { }
}
throw new AssertionError("Expected error of type " + classOf[E] )
}
Run Code Online (Sandbox Code Playgroud)
工作的代码assert很好,但我有两个问题assertThrows.
E在最后一行使用.无论我做什么,我都会得到一个class type expected but E found error.throw new AssertionError("error expected")例如替换它),我得到这个:warning: abstract type E in type pattern is unchecked since it is eliminated by erasure我认为我遇到的两个问题与Scala(可能是java)处理抽象类型的方式有关,以及它们是如何完成的.
我该如何修复我的assertThrows?
加分点:我指定"块类型"(f: => Unit)的方式是正确的吗?
Java虚拟机通过类型擦除来实现泛型,因此在方法体内JVM实际上并不知道E是什么类型,因此AssertThrows方法无法按照您的方式工作.您需要为异常类隐式传递Manifest,如下所示:
def assertThrows[E](f: => Unit)(implicit eType:ClassManifest[E]) {
Run Code Online (Sandbox Code Playgroud)
然后你可以在正文中使用它来捕获异常或获取类名,如下所示:
try {
f
} catch {
case e: Exception =>
if ( eType.erasure.isAssignableFrom(e.getClass))
return;
}
throw new AssertionError("Expected error of type " + eType.erasure.getName )
}
Run Code Online (Sandbox Code Playgroud)
感谢Spring框架的AssertThrows类向我展示了如何做到这一点.