Scala 方法检查任何类型的引用相等性
我正在尝试为任何类型(包括原语)创建一个匹配引用相等的方法。如何最好地做到这一点Scala 方法检查任何类型的引用相等性,scala,equals,Scala,Equals,我正在尝试为任何类型(包括原语)创建一个匹配引用相等的方法。如何最好地做到这一点 eq仅在AnyRef上定义。如果我们尝试 def refEquals[A <% AnyRef, B <% AnyRef](a: A, b: B) = a eq b 但这不起作用(refEquals(1.0,1.0)给出了false),原因如下: 那么,我们如何实现这种方法呢 编辑:应该说“引用类型的引用相等,或者基本类型的值相等” 编辑:以下是使用Rex答案中的想法的方法,适用于需要该方法但不喜欢键入
eq
仅在AnyRef
上定义。如果我们尝试
def refEquals[A <% AnyRef, B <% AnyRef](a: A, b: B) = a eq b
但这不起作用(refEquals(1.0,1.0)
给出了false
),原因如下:
那么,我们如何实现这种方法呢
编辑:应该说“引用类型的引用相等,或者基本类型的值相等”
编辑:以下是使用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]
}
您首先捕获所有基本体,然后进入eq:
def refEquals(a: Any, b: Any) = a match {
case x: Boolean => b match {
case y: Boolean => x==y
case _ => false
}
case x: Byte =>
...
case _ => a.asInstanceOf[AnyRef] eq b.asInstanceOf[AnyRef]
}
您首先捕获所有基本体,然后进入eq:
def refEquals(a: Any, b: Any) = a match {
case x: Boolean => b match {
case y: Boolean => x==y
case _ => false
}
case x: Byte =>
...
case _ => a.asInstanceOf[AnyRef] eq b.asInstanceOf[AnyRef]
}
未定义基元类型的引用相等,因为它们不是引用。在这种情况下,平等的唯一概念是价值平等 但是,如果您想让代码同时使用基本体和引用类型,可以使用“==”并确保传递的对象不重新定义“等于”,或者定义自己的相等对象并传递它。您可能可以使用“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)))
def myRefEquals[A](x:A,y:A)(隐式等式:等效[A]){
当量(x,y)
}
隐式def anyRefHasRefEquality[A基元类型的引用相等是未定义的,因为它们不是引用。在这种情况下,唯一的相等概念是值相等
但是,如果您想让代码同时处理基元和引用类型,可以使用“==”并确保传递不重新定义“等于”的对象,或者定义自己的相等对象并传递它。您可能可以使用“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)))
def myRefEquals[A](x:A,y:A)(隐式等式:等效[A]){
当量(x,y)
}
隐式def anyRefHasRefEquality[A有没有办法检查两个原语是否为相同的类型?当前,对于myRefEquals(1,1.0),它返回true
)
@luigipling当方法看到它们时,它们是相同的类型,因为编译器插入了从Int
到Double
的隐式转换。避免这种情况的唯一方法(我认为)是方法采用(x:Any,y:Any)
。有没有办法检查两个原语是否是相同的类型?目前,对于myRefEquals(1,1.0)
@luigipling,当方法看到它们时,它们返回true
,因为编译器插入了从Int
到Double
的隐式转换。唯一避免这种情况的方法(我认为)表示采用的方法(x:Any,y:Any)
。为什么这不是Any#eq方法的默认设置?@ManuelSchmidt-可能只是为了避免意外的计算开销。eq
检查速度很快。判断八个原语中的哪一个要慢得多。不过,内置一些东西会很好。为什么这不是Any#eq方法的默认设置?@ManuelSchmidt-可能只是为了避免意外的计算开销。eq
检查速度很快。判断您是八个原语中的哪一个要慢得多。不过,内置一些东西会很好。