在Scala泛型类'equals'方法中考虑类型参数......是唯一的方法吗? [英] Accounting for type parameters in a Scala generic class 'equals' method... are manifests the only way?

查看:103
本文介绍了在Scala泛型类'equals'方法中考虑类型参数......是唯一的方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个简单的泛型类:

  class EqualsQuestion [T](val value:T)

code>

以下代码可能会解析为false:

< pre $ val a = new EqualsQuestion [Int](5)
val b = new EqualsQuestion [Long](5)
a == b

(是的,这是一个人为的例子,如果类型参数不同,我希望'=='不管这些值是否相同,尽管在这一点上我不确定这是否合理。但是,它让我觉得这是一个有趣的Scala问题,可以通过这个问题进行解答。)



无论如何,我当然还没有能够实现这样一个equals()方法:

  override def equals(obj:任何):Boolean = 
{
obj match {
case that:EqualsQuestion [T] =>
(this.getClass == that.getClass)&& //没有帮助
this.getClass()。isInstance(that)&& //无帮助
//this.value.getClass == that.value.getClass&& //甚至没有编译
this.value == that.value

case _ =>假


$ / code $ / pre
$ b $ p

这个问题是类型擦除,我知道:全部编译器在这一点上知道'T'是一个类型,但它不知道该类型是什么。所以它不能进行比较。



看来2.8可以用清单来解决这个问题,但是...我不太需要注意我该如何在Scala上进行类型擦除?或者,为什么我无法获取我的集合的类型参数?



其他任何方式都可以解决这个问题?

解决方案

能够区分a和b:

  def same(x:EqualsQuestion [_],y:EqualsQuestion [_] )= {
x.value.asInstanceOf [AnyRef] .getClass == y.value.asInstanceOf [AnyRef] .getClass&&
x.value == y.value
}

请注意,这只有T不是一个通用类型本身,例如它不会区分List [Int]和List [Long]。我希望这足够好......


Given a simple generic class:

class EqualsQuestion[T]( val value :T )

it seems reasonable that the following code would resolve to "false":

val a = new EqualsQuestion[Int]( 5 )
val b = new EqualsQuestion[Long]( 5 )
a == b

(Yes, it's a contrived example. In my real code I wanted '==' to fail if the type parameters are different, regardless if the values are the same, though at this point I'm not sure that makes sense. Still, it struck me as an interesting Scala question to puzzle through.)

Anyway, I of course haven't been able to implement such an equals() method:

override def equals( obj :Any ) :Boolean = 
{
    obj match {
        case that :EqualsQuestion[T] => 
                ( this.getClass == that.getClass ) &&  // no help
                this.getClass().isInstance(that) && // no help
                //this.value.getClass == that.value.getClass && // doesn't even compile
                this.value == that.value

        case _ => false
    }
}

The issue is type erasure, I know: all the compiler knows at this point is that 'T' is a type, but it has no idea what that type is. So it can't make comparisons.

It seems 2.8 can address this with manifests, but... I'm not quite to point of grokking How do I get around type erasure on Scala? Or, why can't I get the type parameter of my collections?.

Any other ways around this?

解决方案

The following function seems to be able to distinguish between a and b:

def same(x: EqualsQuestion[_], y: EqualsQuestion[_]) = {
  x.value.asInstanceOf[AnyRef].getClass == y.value.asInstanceOf[AnyRef].getClass && 
  x.value == y.value
}

Please note that this works only if T isn't a generic type itself, e.g. it wouldn't distinguish List[Int] and List[Long]. I hope that's good enough...

这篇关于在Scala泛型类'equals'方法中考虑类型参数......是唯一的方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆