【问题标题】:Extending Scala collections扩展 Scala 集合
【发布时间】:2011-01-29 21:30:25
【问题描述】:

我想派生一个 Scala 内置集合的版本,它扩展了特定泛型类型的功能,例如,

import scala.collection.immutable._
class Tuple2Set[T1,T2] extends HashSet[Tuple2[T1,T2]] {
 def left = map ( _._1 )
 def right = map ( _._2 )
}

但是当我尝试将它与以下测试一起使用时

  new Tuple2Set[String,String]() + (("x","y")) left

我得到以下编译错误

error: value left is not a member of scala.collection.immutable.HashSet[(String, String)]

如何更改课程以使其正常工作?

【问题讨论】:

  • 我是 Scala 新手,谁能解释一下map( _._1 ) 的意思是什么?据我了解,例如set.map(_ + 1) 将创建新的集合,其中元素递增一,但我无法得到_._1 所做的事情
  • @Vetal: @Vetal: (_._1) 在此上下文中与 ((x: Tuple[T1, T2]) => x._1) 相同,_1Tulple2 类中的字段,表示元组的第一个元素。
  • @Easy 谢谢,如果可以的话,我会接受你的回答
  • Vetal, _X 是返回第 x 个组件的元组上的方法。

标签: scala scala-collections


【解决方案1】:

你确定你真的需要扩展 Scala 集合吗?要使上面的代码正常工作,您可以这样做:

class Tuple2Set[T1,T2](set: Set[(T1, T2)]) {
  def left = set map ( _._1 )
  def right = set map ( _._2 )
}

implicit def toTuple2Set[T1, T2](set: Set[(T1, T2)]) = new Tuple2Set(set)

Set[(String, String)]() + (("x","y")) left

在这种情况下,Tuple2Set 只是任何其他Set 实现的包装器。这意味着您不再局限于HashSet,您的方法leftright 也可用于任何其他实现(如TreeSet)。

我认为在大多数情况下,包装或组合+委托比继承效果更好(并且导致的问题更少)。

【讨论】:

  • 您能否分别给出这两个答案,以便分别对它们进行投票?请参阅meta.stackexchange.com/questions/25209/… 了解有关此的官方礼仪。 (是的,你对CanBuildFrom 的解释值得凯文赖特的答案单独回答。)
【解决方案2】:

正如 Kevin Wright 所说,+ 操作将返回 HashSet。类型类CanBuildFrom 用于在map 等操作期间构建新集合。因此,如果您希望 + 返回 Tuple2Set 而不是 HashSet 您应该实现 CanBuildFrom 并使其在伴随对象中隐式可用,如下所示:

object Tuple2Set {
    implicit def canBuildFrom[T1, T2] = 
        new CanBuildFrom[Tuple2Set[T1, T2], (T1, T2), Tuple2Set[T1, T2]] {...}
}

【讨论】:

  • 谢谢,这个答案似乎解决了如何让 + 返回更具体的类型的问题,但我认为一般来说,带有某种包装的解决方案可能会更好。对于我的实际问题,我希望 Tuple2Set 包装一个数据库,然后提供 find、exists 等的“优化”实现。我认为我实际上最好还是在最后编写一个新接口......
【解决方案3】:

您的问题的一般答案有点过于复杂,无法在此处回复。但它已经写在一些web pages

更多上下文的相同材料也在我们的书的第 2 版,Scala 编程,Artima Press。

【讨论】:

    【解决方案4】:

    您的示例不起作用的原因是+ 操作的返回类型是HashSet 而不是Tuple2Set

    使用“pimp my library”模式而不是继承会更幸运。

    【讨论】:

      猜你喜欢
      • 2016-07-08
      • 1970-01-01
      • 2011-05-17
      • 2015-04-10
      • 2011-03-04
      • 2013-04-23
      • 2014-11-15
      • 2022-11-21
      相关资源
      最近更新 更多