Scala:抽象类型和 Mixin

标签 scala types abstract

假设我有两个类,其参数化类型具有相同的标识符

  trait A {
    type O
    def f(a: Int, os: Seq[O]): Int
  }

  trait B {
    type O
    def g(a: Int, o: O): Int = { h1(o) + h2(a) }
    def h1(o: O): Int
    def h2(a: Int): Int = {a/2}
  }

我想创建一个子类来将两者“结合”

  trait C extends A with B {
    def f(a: Int, os: Seq[O]): Int = {
      os.map{ o => g(a, o) }.sum
    }
  } 

最后,我创建了一个 C 实现

  class D extends C {
    type O = Int
    def h1(o: O): Int = {5 * o}
  }

在编写C时,我还不知道O是什么类型——但是,我想限制A.O == B.O 使得在 A.f 的实现中使用 B.g 是“有意义的”。我尝试实现这个,令人惊讶的是 Scala 似乎假设只有一种 type O

  val d = new D
  println(d.f(1, Seq(1,2,3)))

对我来说,这似乎是不正确的 - 为什么 A.OB.O 应该同意?

编辑 我还想指出,如果您像这样对 O 施加约束,

  case class Z()
  case class Z1() extends Z
  case class Z2() extends Z1

  trait A {
    type O <: Z
  }

  trait B {
    type O >: Z2
  }


class D extends C {
    type O = Z1

编译将失败。但是,如果你用这个来代替,

  trait A {
    type O <: Z
  }

  trait B {
    type O <: Z1
  }
  class D extends C {
    type O = Z2

编译成功,一切正常。

最佳答案

我认为 Scala 总是“结合”特征的成员(类型成员和值成员),当两者混合时:

trait A { type T = Int }
trait B { type T = String }

object C extends A with B

给出

overriding type T in trait A, which equals Int; type T in trait B, which equals String needs `override' modifier

(这就是 Scala 处理多重继承问题的方式——无论一个标识符混合多少次,它都只存在一次)。

关于Scala:抽象类型和 Mixin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8102503/

相关文章:

scala - 如何提高基于 String 或 Double 的值的类型安全性?

C 中类型之间的转换

c# - C# 中的变体类型

Python 未实现的方法与抽象方法,哪个更 Pythonic? PyCharm 不喜欢未在基类中实现的方法

C++ - "Cannot declare parameter ' 匿名'为抽象类型”

java - Scala Futures 和 java 8 CompletableFuture

scala - 如何将“丰富我的图书馆”模式应用于Scala集合?

mysql - docker.io - 应用程序和数据库容器之间的 Docker 链接

android - 错误 : Error: Integer types not allowed (at 'layout_height' with value '10' )

C++ : Should we init class from parent or call directly class?