在通用Scala特征上键入匹配

时间:2014-08-22 01:30:19

标签: scala

我只是把我的脚趾浸入仿制药中,我想知道是否有更好的方法来实现以下目标:

我有一个密封的特征,它有一个抽象的名字和一个重写的equals()。我希望重写的equals在类型和名称上匹配。以下是我所拥有的。

sealed trait NamedCampaign[A <: NamedCampaign] {
  def name: String

  override def equals(obj: Any): Boolean = obj match {
    case x: A => x.name == this.name
    case _ => false
  }
}

case class AdCampaign(name: String, objective: String, status: String, buyingType: String) extends NamedCampaign[AdCampaign]
case class AdSet(name: String, status: String, dailyBudget: Int, lifetimeBudget: Int, startTime: Int, endTime: Int, campaign: String) extends NamedCampaign[AdSet]

在外行人的术语中,如果两个对象属于同一个类并具有相同的名称,我希望它们被认为是相等的。这样做有更好/更快/更惯用的方法吗?

1 个答案:

答案 0 :(得分:1)

你所拥有的东西因擦除而无法工作。类型A在运行时尚未知晓。

改编自this related answer

sealed trait NamedCampaign[A <: NamedCampaign] {
  implicit def classTagA: ClassTag[A]
  def name: String
  override def equals(obj: Any): Boolean = obj match {
    case classTagA(x) => x.name == this.name
    case _ => false
  }
}

case class AdCampaign(name: String, objective: String, status: String,
  buyingType: String)(implicit val classTagA: ClassTag[AdCampaign])
  extends NamedCampaign[AdCampaign]

case class AdSet(name: String, status: String, dailyBudget: Int,
  lifetimeBudget: Int, startTime: Int, endTime: Int, campaign: String)
  (implicit val classTagA: ClassTag[AdSet]) extends NamedCampaign[AdSet]

更好的方法是使用canEqual方法。

sealed trait NamedCampaign {
  def name: String
  def canEqual(that: Any): Boolean
  override def equals(other: Any): Boolean = other match {
    case that: NamedCampaign => (that canEqual this) &&
                                (this.name == that.name)
    case _ => false
  }
}

case class AdCampaign(name: String, objective: String, status: String,
    buyingType: String) extends NamedCampaign {
  override def canEqual(that: Any) = that.isInstanceOf[AdCampaign]
}

case class AdSet(name: String, status: String, dailyBudget: Int,
    lifetimeBudget: Int, startTime: Int, endTime: Int, campaign: String)
    extends NamedCampaign {
  override def canEqual(that: Any) = that.isInstanceOf[AdSet]
}

我的两分钱:我认为在案例类中覆盖equals是不合适的。当你想要比较所有领域(你可能想要做的,比如单元测试)时,你会后悔。