为什么一个'Any`铸造的`String`对象不再被认为是String(而另一种方式是它)?

Joh*_*ood 0 types scala

将String转换为类型时Any,不会再将其自动视为String- 为什么?请参阅以下示例:

val str = "foo"
val strAsAny = "bar".asInstanceOf[Any]
def f1(x: String) = println(x.toString)
def f2(x: Any) = println(x.toString)

f1(str) // works, type exactly given
f2(str) // works, subtype of Any given

f1(strAsAny) // works not, but strAsAny.isInstanceOf[String] = true !
f2(strAsAny) // works, type exactly given
Run Code Online (Sandbox Code Playgroud)

这让我感到困惑,因为两个值仍然具有类型String:

scala> str.isInstanceOf[String]
res4: Boolean = true

scala> strAsAny.isInstanceOf[String]
res5: Boolean = true
Run Code Online (Sandbox Code Playgroud)

我的猜测是,只有类型转换"向上移动"的interhitance-chain才会自动完成.它是否正确 ?

Rex*_*err 5

类型指定您期望的内容,而不是您实际获得的内容.您可以将满足您期望的任何内容放入该插槽中.

有了Any,你期望很少,所以任何事情都有效.有String,你期望length,charAt等等.所以a String可以满足一个Any但不反过来的要求.如果你碰巧把一个String插入一个Any插槽,你现在只承诺做Any可以做的事情,所以你不能把这个值和它给予期待的东西String.

这被称为Liskov替换原则,是(安全)面向对象设计的基本原则.