与具有泛型类型的值进行模式匹配
我正在编写基于树的表达式计算器,并且在类型擦除方面遇到了一些麻烦。
树看起来像
sealed abstract class Node[+T]
case class Var[+T](name:String) extends Node[T]
/* SNIP */
评估器是
def eval[T](node:Node[T], context:Map[String, Any]):Option[T] = node match {
case Var(name) => context.get(name) match {
case Some(value:T) => Some(value)
case _ => None
}
/* SNIP */
}
代码编译的,但对 Var
节点的类型检查不起作用。所以这个测试失败了:
class ContextEvaluatorTest extends FunSuite with ShouldMatchers {
test("evaluation with type mismatch") {
ContextEvaluator.eval(Var[Int]("a"), Map("a" -> "not int")) should equal (None)
}
}
错误消息是
org.scalatest.TestFailedException: Some(not int) did not equal None
情况看起来像是清单的用例,但我无法正确添加它们。
I'm writing tree-based expression evaluator, ans I've run into some troubles with type-erasure.
Tree looks like
sealed abstract class Node[+T]
case class Var[+T](name:String) extends Node[T]
/* SNIP */
The evaluator is
def eval[T](node:Node[T], context:Map[String, Any]):Option[T] = node match {
case Var(name) => context.get(name) match {
case Some(value:T) => Some(value)
case _ => None
}
/* SNIP */
}
The code compiles, but type checks on Var
nodes don't work. So this test fails:
class ContextEvaluatorTest extends FunSuite with ShouldMatchers {
test("evaluation with type mismatch") {
ContextEvaluator.eval(Var[Int]("a"), Map("a" -> "not int")) should equal (None)
}
}
Error message is
org.scalatest.TestFailedException: Some(not int) did not equal None
Situation looks like a use-case for manifests, but I couldn't add them properly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这似乎有效:
但请注意
T
必须是简单类型,据我所知ClassManifest
无法区分List[Int]
和列表[字符串]
。也许 Manifest 可以做到这一点,但是调查比在底层类上调用 isInstance 更复杂。This seems to work:
Note however that
T
must be a simple type, AFAIKClassManifest
can't distinguish between things likeList[Int]
andList[String]
. ProbablyManifest
can do that, but then the investigation is more complicated than callingisInstance
on the underlying class.它不起作用,因为
T
被擦除。这意味着模式匹配中的value: T
是没有意义的。事实上,编译器应该对此发出警告。您必须求助于使用清单来进行该测试。请参阅 Landei 的 答案作为示例。
It doesn't work because
T
is erased. That meansvalue: T
in the pattern match is meaningless. In fact, the compiler should have warned you about that.You'll have to resort to using manifests to make that test. See Landei's answer for an example.