如何定义扩展此特征的任何事物
请参阅以下代码片段:
trait Fruit {
val color:String
def == (fruit:Fruit) = this.color == fruit.color
}
case class Orange(color:String) extends Fruit
case class Apple(color:String) extends Fruit
正如预期的那样,Orange("red") == Orange("red")
为 true
。但是,我想强制只能比较相同类型的水果,因此例如 Orange("red") == Apple("red")
应该给出错误。我们能否以一种优雅的方式在特质 Fruit
的 ==
签名中强制执行这一点?
编辑:我希望在编译时捕获错误,而不是在运行时捕获。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Scalaz 有一个 Equal “类型类”来解决这个问题,尽管使用了不同的运算符。
https://github.com/scalaz/scalaz/blob/ master/core/src/main/scala/scalaz/Equal.scala
它的核心基本上是这样的(尽管我在他们使用一些 unicode 的地方使用 === )
并且像这样使用
Scalaz has an Equal "type class" that solves this problem, albeit with a different operator.
https://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/Equal.scala
The heart of it is basically this (although I use === where they use some unicode)
And is used like so
不幸的是,您无法静态地检查这一点...至少不能使用
==
,它使用 Java 的Object#equals
方法,其中所有内容都强调以原始方式定义对象。如果您想要类型安全,那么您唯一的选择是实现另一个运算符,可能类似于
=|=
,然后将其与类型类结合起来以确保您的安全。我相信 scalaz 对于类型安全相等也有一些有用的东西,但对这个库的了解还不足以肯定地说明这一点。
您可以采取的另一种方法(仅在运行时安全)是使用
canEqual
模式 如此处所述。这已经被案例类使用,并提供了一种在适合相等时选择性地破坏 LSP 的好方法。Unfortunately, you can't check this statically... At least, not using
==
, which uses Java'sObject#equals
method where everything is emphatically defined in terms of raw objects.If you want type safety, then your only choice is to implement another operator, perhaps something like
=|=
, then combine this with type classes to ensure your safety.I believe that scalaz also has something useful for type-safe equality, but don't know the library well enough to state this for certain.
The other approach you can take, which will only be safe at runtime, is to use the
canEqual
pattern as described here. This is already used by case classes and offers a nice way to selectively break the LSP when it's appropriate for equality.如果您愿意将该方法的名称从 == 更改为其他名称,我们可以这样做:
然后,如果我们将 Apples 与 Oranges 进行比较,我们会得到:
Apples 与 Apples of the same color 我们会得到:
Apples with Apples of a different我们得到的颜色:
If you are happy to change the name of the method from == to something else we could do this:
Then if we compare Apples with Oranges we get:
and Apples with Apples of the same color we get:
and Apples with Apples of a different color we get:
尝试:
Try: