Scala的常规值赋值与提取器赋值不平衡的原因是什么?

时间:2016-02-23 17:55:07

标签: scala scala-2.11

Scala似乎在提取过程中对常规值赋值与赋值具有不同的语义。这为我创建了一些非常微妙的运行时错误,因为我的代码库随着时间的推移而迁移。

举例说明:

case class Foo(s: String)

def anyRef(): AnyRef = { ... }

val Foo(x) = anyRef() // compiles but throws exception if anyRef() is not a Foo

val f: Foo = anyRef() // does not compile

我不明白为什么两个val赋值行在编译/运行时行为方面会失衡。

有些我很好奇:这种行为有原因吗?它是否是实现提取方式的不良后果?

(在Scala 2.11.7中测试)

1 个答案:

答案 0 :(得分:2)

是的,有。

如果是提取器,则指定您希望在此位置匹配的模式。这被转换为从Any到Option [String]的一个提取器方法的调用,并且可以使用您提供的AnyRef类型的值调用此方法。你只是断言,你确实得到了一个结果而不是“无”。

在另一行中,您使用的是类型注释,即您明确指定了“f”的类型。但是你要分配一个不兼容的值。

当然编译器可以添加隐式类型转换,但是使类型转换变得如此简单并不适合像Scala这样的语言。

您还应该记住,提取器与类型无关。在模式Foo(x)中,名称Foo与Foo类型无关。它只是一个提取器方法的名称。

以这种方式使用模式当然是一个非常动态的功能,但我认为这是故意的。