【问题标题】:Dependency in traits inheritance特征继承中的依赖
【发布时间】:2010-01-20 10:45:41
【问题描述】:

在 Scala 中,如何将容器特征(如 Traversable[Content])添加到另一个扩展容器的特征(因此对其内容的可见性有限?

例如,下面的代码尝试为需要 Traversable 的容器定义一个 trait WithIter(当然,实际上我在 Container 中还有其他东西)。

import scala.collection._

trait Container {
  type Value
}

trait WithIter extends Container with immutable.Traversable[Container#Value]

class Instance extends WithIter {
  type Value = Int
  def foreach[U](f : (Value) => (U)) : Unit = {}
}

编译器(scalac 2.8.0.Beta1-RC8)发现错误:

错误:类 Instance 需要是抽象的,因为 [U](f: (Container#Value) => U)Unit 类型的特征 GenericTraversableTemplate 中的方法 foreach 未定义

有什么简单的方法吗?

【问题讨论】:

    标签: scala


    【解决方案1】:
    class Instance extends WithIter {
      type Value = Int
      def foreach[U](f : (Container#Value) => (U)) : Unit = {}
    }
    

    如果您在谈到内部类时未指定OuterClass#,则将假定为this.(即特定于实例)。

    【讨论】:

    • 我对这个结构有点困惑。你不能说: new Instance().foreach( (x : Int) => x + 1)。为什么要这样定义?
    • 当您想要一些行为类似于 Int 但不兼容的东西时,此构造可能很有用——例如,如果您要定义货币或计量单位。
    • @Thomas:这不是 my 构造。鉴于问题对WithIter 的定义,这是声明Instance 的正确方法。
    • 这和trait Container[T]{val a : T}一样。但是新的Instance().foreach( (x : Int) => x + 1) 不与抽象类型成员一起使用,而是与泛型定义一起使用。
    • @Thomas 一个是类型参数,另一个是抽象类型。它们并不完全相同,即使它们非常接近。特别是不能引用Container#TContainter.T,因为T不是类型,只是参数。另一方面,在示例中,Value 本身就是一个类型。
    【解决方案2】:

    为什么要使用抽象类型?泛型很简单:

    import scala.collection._
    
    trait Container[T] {}
    
    trait WithIter[T] extends Container[T] with immutable.Traversable[T]
    
    class Instance extends WithIter[Int] {
      def foreach[U](f : (Int) => (U)) : Unit = {println(f(1))}
    }
    
    
    new Instance().foreach( (x : Int) => x + 1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-23
      • 1970-01-01
      • 2021-02-12
      • 2020-11-11
      • 1970-01-01
      • 2013-04-01
      • 2023-03-28
      • 1970-01-01
      相关资源
      最近更新 更多