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
检查速度很快。判断您是八个原语中的哪一个要慢得多。不过,内置一些东西会很好。