假设Foo
是一个简单的案例类,在以下表达式的值为2
的情况下是什么情况?
Option(myFoo) match {
case Some(x: Foo) => 1
case Some(x) if x.isInstanceOf[Foo] => 2
case _ => 3
}
有关此问题的背景信息,请参阅Loss of type info in servlet code。
答案 0 :(得分:1)
第一和第二种情况是等效的。
这是您将函数反编译回java(使用scala-to-java):
Scala的:
type Foo = String
def test(foo:Any) = Option(foo) match {
case Some(x: Foo) => 1
case Some(x) if x.isInstanceOf[Foo] => 2
case _ => 3
}
爪哇:
import scala.*;
public final class _$$anon$1 {
private int test(final Object foo) {
boolean b = false;
Some<Object> some = null;
final Option<Object> apply = Option$.MODULE$.apply(foo);
if (apply instanceof Some) {
b = true;
some = (Some<Object>)apply;
final Object x = some.x();
if (x instanceof String) {
return 1;
}
}
if (b) {
final Object x2 = some.x();
if (x2 instanceof String) {
return 2;
}
}
return 3;
}
}
更新!
对于内部类,模式匹配似乎有所不同:
case class Wrapper(wrapped: String)
def test(a:Any) = Option(a) match {
case Some(x:Wrapper) => x
case Some(x) if x.isInstanceOf[Wrapper] => x
case x => ???
}
产生类似的东西:
private Object test(final Object a) {
boolean b = false;
Some<Object> some = null;
final Option<Object> apply = Option$.MODULE$.apply(a);
if (apply instanceof Some) {
b = true;
some = (Some<Object>)apply;
final Object x = some.x();
if (x instanceof _$$anon$1$Wrapper && ((_$$anon$1$Wrapper)x)._$$anon$Wrapper$$$outer() == this) {
return x;
}
}
if (b) {
final Object x2 = some.x();
if (x2 instanceof _$$anon$1$Wrapper) {
return x2;
}
}
throw Predef$.MODULE$.$qmark$qmark$qmark();
}
因此,它还检查“外部”字段,即外部类。如果您无法控制您的环境,例如您无法保证外部类始终是同一个实例,则模式匹配可能会失败(并且发现这一点非常令人沮丧)。
答案 1 :(得分:-1)
如果x不是Foo类的实例,请说任何类型但Foo类型。但是抱歉,在任何情况下都不会是2,如果x.isInstanceOf [Foo]使案例1和case2是相同的情况。 假设你有这个代码
def f(t:Any) = Option(t) match {
case Some(x: Foo) => 1
case Some(x) if x.isInstanceOf[Foo] => 2
case _ => 3
}