Dotty类型类的扩展vs中缀特征方法

问题描述

我经历了documentation,并找到了几种方法来定义类型类实例的即席行为。这是原始示例:

trait Ord[T] {
  def compare(x: T,y: T): Int
  extension (x: T) def < (y: T) = compare(x,y) < 0
  extension (x: T) def > (y: T) = compare(x,y) > 0
}

有趣的是,我们可以定义一堆普通的infix方法以及扩展名。用户期望的行为应该相同(尽管实现上有所不同)。

trait RankEq[T]:
  extension (x: T)
    def equal (y: T): Boolean

  extension (x: T)
    def notEqual (y: T): Boolean = !rankEqual(y)

trait RankOrd[T] {
  def rankCompare(x: T,y: T): Int

  def (x: T) isLower (y: T): Boolean =
    rankCompare(x,y) == -1

  def (x: T) isHigher (y: T): Boolean =
    rankCompare(x,y) == 1
}

下面的示例说明了这一点:

given rankEq as RankEq[Rank] {
  extension (x: Rank)
    def equal (y: Rank) = (x.ordinal - y.ordinal) == 0
}

given rankOrd as RankOrd[Rank] {
  override def rankCompare(x: Rank,y: Rank): Int = {
    x.ordinal - y.ordinal
  }
}

object Rank {
  def beats(r1: Rank,r2: Rank)
       (using RankEq[Rank])(using RankOrd[Rank]): Boolean = {
    
    if r1.equal(r2) then false    // extension methods
    else r1.isHigher(r2)            // trait-member infix method 
  }
}

由于两个结构都在做相同的事情(以不同的方式),所以提出了一个问题:哪种方式最惯用?如果两者都适用,哪种情况下效果最好?

谢谢!

解决方法

if r1.equal(r2) then false    // extension methods
else r1.isHigher(r2)          // trait-member infix method 

实际上,

trait RankOrd[T] {
  def (x: T) isHigher (y: T): Boolean
}

是扩展方法的前语法,

trait RankEq[T] {
  extension (x: T) def equal (y: T): Boolean
}

currentextension methods语法。

因此,“特质成员固定方法”是使用前一种语法编写的扩展方法。

查看提交

https://github.com/lampepfl/dotty/commit/6ff0ac8694d4e3b84ed9b15fb277f429c6767faa

我猜当前受支持的两种语法都是暂时的。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...