我把它写成了一个REPL:
case class Thingy(s: String) val things = List(Thingy("x"),Thingy("y")) things.indexOf("x")
返回-1.但我原本以为它不会编译,因为“x”是一个字符串,而不是一个Thingy.实际上,事实证明你将什么类型放入indexOf并不重要:
things.indexOf(42) things.indexOf(java.time.LocalDate.Now())
这些都返回-1.
indexOf有这个签名:
def indexOf[B >: A](elem: B): Int
我认为>:意味着B应该是A的超类型,但这些类都不是我的案例类Thingy的超类型.
我在这里错过了什么?
解决方法
B被推断为java.io.Serializable,它是String和Thingy.1的超类型
这是两件事的不幸后果:
> Scala的所有/大多数值共享的多余父类型(Any,Object,Serializable等).
>列出协变.2
将indexOf定义为
def indexOf(elem: A): Int
将A置于逆变位置,这是不允许的,因为它会违反Liskov替换原则:List [Thingy]是List [Any],你可以在List [Any]上调用.indexOf(“x”) ],因此你应该能够在List [Thingy]上调用.indexOf(“x”).
1如果他们没有碰巧实现Serializable,它仍然会推断Any.
2这是选择不变集合的原因,例如scalaz.IList.
3尝试 – 它不会编译:trait Foo [A] {def bar(a:A)}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。