![](/img/trans.png)
[英]Scala: Problems with erasure on overriding equals function for parametrized classes
[英]Scala: Overriding equals for value classes
为了在我们的代码库中获得更多的类型安全性,我们已开始用类型安全值类替换通用Strings,Ints等,但是我正在努力使它们方便地与==
运算符和文字一起使用。 希望有人可以帮助我。
我们的值类的定义和使用方式如下:
case class Name(value: String) extends AnyVal {}
object Name { implicit def to(something:String): Name = Name(something) // convenience }
case class Address(value: String) extends AnyVal {}
object Address { implicit def to(something:String): Address = Address(something) // convenience }
case class Person(name: Name, address: Address) {
def move(newAddress: Address) = copy(address=newAddress)
}
val somebody = Person("Pete", "Street 1")
somebody.move(Address("Street 2")) // allowed
somebody.move(somebody.name) // not allowed, which is exactly what we want
somebody.move("Street 2") // allowed by convenience
现在,我希望他们能够“自然地”比较其内在value
:
Name("Pete") == "Pete" // should be true, but evaluates to False
我可以通过覆盖equals
来解决此问题:
case class Name(value: String) extends AnyVal {
override def equals(other: Any) =
if (other.isInstanceOf[Name])
other.asInstanceOf[Name].value == this.value
else if (other.isInstanceOf[String])
other == this.value
else
false
}
Name("Pete") == "Pete" // now evaluates to true
但是,此解决方案不是对称的:
"Pete" == Name("Pete") // evaluates to false, because it is using String.equals
我不知道该如何解决。 甚至没有声明从Name到String的隐式转换会有所帮助(而且我更希望不要有这种东西)。 可以做我想做的事吗?
编辑:我可能对此不清楚,但是我并不是真正在寻求有关软件开发的建议。 这是一个技术问题:能否在Scala中完成?
我有做我描述的原因,但是可悲的是,它们与成千上万的Scala代码行有关,无法在简短的堆栈溢出问题中传达。
我认为,您应该只是摆脱convenience
隐式。 他们达到了目的:
val john = Person("Street 1", "John") // mixed up order
john.move("Pete") // Yup, I can "move" to a name ...
现在,约翰(John)是一个名为“街道1”的人,住在地址“皮特”。 在定义所有值类的麻烦之后,这不是您要允许的。
我不认为==
可以在这种情况下工作。 您可能要做的是定义一个不同的比较操作。
case class Name(value: String) extends AnyVal {
def is(n: Name): Boolean = value == n.value
}
您还必须扩大隐式转换器的范围,以便可以为这些转换访问它。
implicit def toName(something:String): Name = Name(something) // not in object
现在这有效。
val somebody = Person("Pete", "Street 1")
somebody.move(Address("Street 2")) // allowed
somebody.move("Street 2") // allowed by convenience
somebody.name is "Pete" // true
"Pete" is somebody.name // true
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.