我正在尝试创建一个方法,它将匹配任何类型的引用相等,包括基元.怎么做到最好?
eq仅定义于AnyRef.如果我们尝试
def refEquals[A <% AnyRef, B <% AnyRef](a: A, b: B) = a eq b
Run Code Online (Sandbox Code Playgroud)
然后在运行时refEquals(1,2)我们发现有一些隐含的方法可以Predef包括int2IntegerConflict破坏这样的转换.
我试过这个:
def refEquals(a: Any, b: Any) = a match {
case x: AnyRef => b match {
case y: AnyRef => x eq y
case _ => false
}
case x: Any => b match {
case y: AnyRef => false
case y: Any => x == y
}
}
Run Code Online (Sandbox Code Playgroud)
但是由于Rex Kerr refEquals(1.0, 1.0)给出false的原因,这不起作用(给出):与AnyRef的奇怪模式匹配行为
那么我们如何实现这样的方法呢?
编辑:应该说"引用类型的引用相等,或原始类型的值相等".
编辑:这是使用Rex答案的想法的方法,对于任何需要这个并且不喜欢打字的人:
def refEquals(a: Any, b: Any) = a match {
case x: Boolean if b.isInstanceOf[Boolean] => x == b
case x: Byte if b.isInstanceOf[Byte] => x == b
case x: Short if b.isInstanceOf[Short] => x == b
case x: Char if b.isInstanceOf[Char] => x == b
case x: Int if b.isInstanceOf[Int] => x == b
case x: Float if b.isInstanceOf[Float] => x == b
case x: Double if b.isInstanceOf[Double] => x == b
case x: Long if b.isInstanceOf[Long] => x == b
case _ => a.asInstanceOf[AnyRef] eq b.asInstanceOf[AnyRef]
}
Run Code Online (Sandbox Code Playgroud)
对于基本类型,引用相等性是未定义的,因为它们不是引用.在这种情况下,唯一的平等概念是价值平等.
但是,如果您希望代码同时使用基元和引用类型,则可以使用"=="并确保传递不重新定义"等于"的对象,或者定义自己的相等对象并传递它.你可以使用'scala.math.Equiv [T]'.
def myRefEquals[A](x: A, y: A)(implicit eq: Equiv[A]) {
eq.equiv(x, y)
}
implicit def anyRefHasRefEquality[A <: AnyRef] = new Equiv[A] {
def equiv(x: A, y: A) = x eq y
}
implicit def anyValHasUserEquality[A <: AnyVal] = new Equiv[A] {
def equiv(x: A, y: A) = x == y
}
println(myRefEquals(Some(1), Some(1)))
Run Code Online (Sandbox Code Playgroud)
这假设您希望两个对象具有相同的类型.
| 归档时间: |
|
| 查看次数: |
370 次 |
| 最近记录: |