扩展 Scala 集合

发布于 2024-10-14 19:43:52 字数 475 浏览 1 评论 0原文

我想派生一个 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)]

如何更改该类这有效吗?

I would like to derive a version of a Scala built-in collection that expands on the functionality for a particular generic type e.g.,

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

However when I try to use it with the following test

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

I get the following compile error

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

How can I change the class so that this works?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦明 2024-10-21 19:43:52

您确定确实需要扩展 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)上使用。

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

Are you sure you really need to extend Scala collection? To make the code above work you can do this:

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

In this case Tuple2Set is just the wrapper for any other Set implementations. This means you are not limited to HashSet anymore and your methods left and right will be available on any other implementations as well (like TreeSet).

I think in most cases wrapping or composition+delegation works much better than inheritance (and causes less problems).

予囚 2024-10-21 19:43:52

正如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]] {...}
}

As Kevin Wright said, + operation will return back HashSet. Type class CanBuildFrom is used to build new collections during operations like map. So if you want + to return Tuple2Set instead of HashSet you should implement CanBuildFrom and make it implicitly available in companion object like this:

object Tuple2Set {
    implicit def canBuildFrom[T1, T2] = 
        new CanBuildFrom[Tuple2Set[T1, T2], (T1, T2), Tuple2Set[T1, T2]] {...}
}
微凉徒眸意 2024-10-21 19:43:52

您的问题的一般答案对于此处的回复来说有点过于复杂。但它已经写在一些 网页

具有更多上下文的相同材料也包含在我们的书《Scala 编程》(Artima Press)的第二版中。

The general answer to your question is a bit too involved for a response here. But it has been written up in some web pages.

The same material with more context is also in the 2nd edition of our book, Programming in Scala, Artima Press.

电影里的梦 2024-10-21 19:43:52

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

使用“为我的图书馆拉皮条”模式而不是继承,你会更幸运。

The reason your example doesn't work is that the return type of the + operation is a HashSet and not a Tuple2Set.

You'll have much more luck using the "pimp my library" pattern instead of inheritance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文