微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Scala indexOf接受一切

我把它写成了一个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 举报,一经查实,本站将立刻删除。

相关推荐