为了在我们的代码库中获得更多的类型安全性,我们已经开始用类型安全值类替换泛型字符串,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代码的代码库有关,并且无法在短堆栈溢出问题中传达。