【问题标题】:Generically typed classes in collections in ScalaScala集合中的泛型类
【发布时间】:2011-11-30 14:58:34
【问题描述】:

我在 Scala 中创建的泛型类有问题。我有以下课程:

class Channel[T, U](val endPoint : EventSource[U], val filter : Occurrence[T] => Boolean,
    val map : Occurrence[T] => Occurrence[U]) {

    def send(occurrence : Occurrence[T]) {
        if (filter(occurrence)) {
            endPoint.occur(map(occurrence))
        }
    }
}

这里可以将 Channel[T,U] 视为将 Occurrence[T] 从 EventSource[T] 传播到 EventSource[U] 的一种方式。仅当过滤器函数为真时才发送出现,如果是,则将出现传递给 map 并发送结果。

这个类似乎可以正确编译和运行。我的问题是我想将多个 Channel 附加到 EventSource[T] 实例,以便它可以将 Occurrences 传播到不同类型的多个不同 EventSource。我的困惑基本上是如何做到这一点:

class EventSource[T] {
    var List[Channel[T,U]] list = ...
}

你在这里是什么? T 只是从 list 所属的 EventSource 中的类型 T 引用(是其中的成员)。

对不起,如果这含糊不清或令人困惑!

编辑:我应该注意到我也希望能够附加到这个列表中:

list = list ++ List[Channel[T, U](new Channel[T, U](endPoint, filter, map))

追加是真正的问题吗?

【问题讨论】:

    标签: generics scala types collections typing


    【解决方案1】:

    如果我正确理解您的问题,您可以使用 Any:

    class EventSource[T] {
      val list: List[Channel[T, Any]] = ...
    

    编辑:您使用附加的代码示例是否被复制?因为我注意到您缺少 Channel 的类型。 此外,如果您只想在列表中添加一个元素,您可以使用 cons,它将新元素添加到列表的开头:

    Channel[Your, Types](your, para, meters)::list
    

    如果您出于某种原因绝对想将新元素添加到该列表的end,您可以使用:+

    【讨论】:

    • 我以前试过这个,但它不适用于附加。我已经用我的意思更新了这个问题。
    • 这恼人的问题与 U 在 Channel 中的不变性相同,因此 Channel[T, U](其中 U 是任何东西)不能 consed 到 List[T, Any]。感谢您的帮助和快速更新?
    • @Oetzi,你必须在使用 Channel 时输入它,这意味着你不能写 Channel[T, U]::list,你必须写 Channel[Real, Type]::list。还是我误会了你?你得到的错误信息到底是什么?
    • 错误:类型不匹配;找到:com.github.oetzi.echo.core.Channel[T,T] 要求:com.github.oetzi.echo.core.Channel[T,Any] 注意:T <: any channel u this.edges="new" t func occ=""> occ) :: this.edges
    【解决方案2】:

    要保持打字,您确实需要使用通配符 _ type。这允许您以这样一种方式定义列表,即您在将 Channel 类型的 U 参数添加到列表时关心它,而不是在向列表中的所有通道发送事件时关心它。以下编译,但就目前而言,它是相当循环的。你需要一个通道的子类来做一些事情,而不是把它发送到另一个 EventSource。

    class Occurrence[T]
    class Channel[T, U](val endPoint : EventSource[U], val filter : Occurrence[T] => Boolean,
        val map : Occurrence[T] => Occurrence[U]) {
        def send(occurrence : Occurrence[T]) {
            if (filter(occurrence))
                endPoint.occur(map(occurrence))
        }
    }
    class EventSource[T] {
      var list: List[Channel[T,_]]  = Nil
      def addChannel[U]( endPoint : EventSource[U], filter : Occurrence[T] => Boolean, map : Occurrence[T] => Occurrence[U]) {
        list = list ++ List[Channel[T, U]](new Channel[T, U](endPoint, filter, map))
      }
      def occur( occurrence : Occurrence[T] ) {
        list foreach { _.send( occurrence ) }
      }
    }
    

    【讨论】:

    • “你需要一个通道的子类来做一些事情,而不是把它发送到另一个 EventSource”——我不明白你的意思是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    相关资源
    最近更新 更多