Scala indexOf接受所有内容

时间:2015-06-26 07:20:22

标签: scala

我把它写成了一个REPL:

case class Thingy(s: String)
val things = List(Thingy("x"), Thingy("y"))
things.indexOf("x")

返回-1。但我希望它不会编译,因为"x"String,而不是Thingy。实际上,事实证明,您将indexOf放入的类型并不重要:

things.indexOf(42)
things.indexOf(java.time.LocalDate.now())

这些都返回-1。

indexOf有这个签名:

def indexOf[B >: A](elem: B): Int

我认为>:表示B应该是A的超类型,但这些类都不是我的案例类Thingy的超类型。

我在这里缺少什么?

1 个答案:

答案 0 :(得分:8)

B被推断为java.io.Serializable,这是StringThingy的超类型。 1

这是两件事的不幸后果:

  1. Scala所有/大多数值共享的多余父类型(AnyObjectSerializable等等。
  2. List是协变的。 2
  3. indexOf定义为

    def indexOf(elem: A): Int
    

    会将A置于逆变位置,这是不允许 3 因为它会违反Liskov替换原则:List[Thingy]List[Any] ,您可以在.indexOf("x")上致电List[Any],因此您应该可以.indexOf("x")致电List[Thingy]

    1 如果他们没有碰巧实施Serializable,它仍会推断Any

    2 这是选择不变集合的理由,例如scalaz.IList

    3 试一试 - 它不会编译:{{1​​}}