与压倒一切的抽象类型蛋糕的图案不上类型限制工作与压倒一切的抽象类型蛋糕的图案不上类型限制工作(Cak

2019-05-13 13:36发布

我想覆盖与性状抽象类型<:并且不与= (像答案这里Scala的上界:值不是类型参数中的一员 )。

我想用蛋糕图案,但这是不行的,我不明白为什么?

trait A {
  def ping = println("ping")
}

trait Cake {
  type T
}

trait S { this: Cake =>
  type T = A
  def t: T
  t.ping
}

OK,这个例子中运行,但在我的实际使用情况下,我想重写型<:而不是= 。它似乎是不可能的访问T功能,为什么呢?

trait S { this: Cake =>
  type T <: A
  def t: T
  t.ping
}

返回一个错误value ping is not a member of S.this.T

Answer 1:

这是Scala的类型系统的缺点。 当确定一个mixin成员,斯卡拉使用了两个规则:第一,混凝土始终覆盖抽象。 其次,如果两个成员都是混凝土,或在后来进来的线性化为了胜既抽象,那么一个。

此外,性状的自类型

trait S { this: C => ... }

隐式地扩充到

trait S { this: S with C => ... }

因此,在性状界说可以在S.访问你的情况,性状S被视为:

trait S { this: S with Cake =>
  type T = A
  def t: T
  t.ping
}

现在,只要T是具体的,这是好的,因为它覆盖了抽象吨蛋糕。 但是,如果T是抽象的,那个在蛋糕中的线性顺序和胜后卡梅斯。 而那T没有上限,所以没有成员平。 解决这个问题的方法之一是通过写作来改变线性顺序:

trait S { this: Cake with S =>
  type T <: A
  def t: T
  t.ping
}

如果斯卡拉有不同的规则,即抽象类型成员的所有约束中混入被合并,而不是根据线性化订单拣选一个成员,这将是更清洁。 这就是我们想在未来要考虑的改变,但我们需要小心的向后兼容性。



文章来源: Cake pattern with overriding abstract type don't work with Upper Type Bounds