Scala 3中能否用扩展方法重写父类方法?重写equals未生效
问题原因与解决办法
- 你写的扩展方法不会被Scala的
==运算符触发,这不是实现错误,是Scala 3扩展方法的设计限制。 - Scala中的
==本质是调用java.lang.Object的equals方法,但扩展方法定义的equals并不是目标类(CellTower)的原生成员方法,因此在进行相等判断时,JVM/Scala会优先使用类本身继承自Object的默认equals实现(比较引用),而不会去查找扩展方法。
可行的解决方案
方案1:手动调用扩展方法
如果坚持用扩展方法,需要显式调用,而非依赖==:
cellTower1.equals(cellTower2)
方案2:创建显式包装类
最可靠的方式是定义一个包装类,封装CellTower并实现equals:
case class CellTowerWrapper(cellTower: CellTower) { override def equals(other: Any): Boolean = other match { case that: CellTowerWrapper => this.cellTower.toString == that.cellTower.toString case _ => false } override def hashCode(): Int = cellTower.toString.hashCode() }
之后统一使用CellTowerWrapper(cellTower)实例进行相等判断,==会正常调用重写的equals方法。
方案3:使用Scala 3 opaque类型(推荐)
用opaque类型包装,既保留原类型的使用感,又能自定义equals逻辑:
opaque type CellTowerOps = CellTower object CellTowerOps { def apply(ct: CellTower): CellTowerOps = ct extension (ct: CellTowerOps) { override def equals(other: Any): Boolean = other match { case otherCt: CellTowerOps => ct.toString == otherCt.toString case _ => false } override def hashCode(): Int = ct.toString.hashCode() } }
使用时通过CellTowerOps(cellTower)转换为opaque类型,之后==就能正常触发自定义的equals逻辑。
内容的提问来源于stack exchange,提问作者Chris W.
相关产品推荐
相关产品推荐

