gpt4 book ai didi

scala - 扩展内置集合,内置方法的问题

转载 作者:行者123 更新时间:2023-12-02 08:57:53 27 4
gpt4 key购买 nike

我是 Scala 新手,所以如果这是一个愚蠢的问题请原谅我,但这里是......

假设我希望创建一个包含附加方法的扩展 Map 类型。我可以看到几种方法来做到这一点。第一个是组合:

class Path[V](val m: Map[V, Int]) {
// Define my methods
}

另一种方法是通过继承,例如

class Path[V] extends Map[V, Int] {
// Define my methods
}

最后,我还考虑了“特质”路线,例如

trait Path[V] extends Map[V, Int] {
// Define my methods
}

构图有点尴尬,因为你必须不断地引用里面的东西。继承是相当自然的事情,但对我来说有一个问题(稍后会详细介绍)。 Traits 似乎是一种非常优雅的方法,使用“with”结构确实很好,但对我来说也有一个问题。

我遇到的问题是像++ 这样的方法。他们归还了一张新 map 。因此,假设上面提到的“我的方法”希望向 map 添加一些内容(只是一个例子,我知道 map 已经有这个),例如

trait Path[V] extends Map[V,Int] {
def addOne(v: V, i: Int): Path[V] = this + (v -> i)
}

这会生成错误,因为返回类型不是 Path[V]。现在我知道我可以在新实例上使用“with”来添加 Path[V] 特征。但我不控制这里新 map 的构建。有什么方法可以添加 Path[V] 特征吗?我考虑过创建一个预先填充的新的不可变 map ,然后标记“with Path[V]”,但没有这样的构造函数可以用来创建预先填充的 map 。

我怀疑(尽管我还没有证实)使用继承也会遇到类似的问题。我可以添加一个新方法来向 map 添加新条目,但我不会返回我想要的“Path[V]”。组合方法似乎是唯一的方法。

我希望这一点很清楚。评论?

最佳答案

也许最简单的方法是使用 MapProxy 特征:

import collection._

class Path[V](val self: Map[V, Int]) extends MapProxy[V, Int] {
// without the companion object below
def addOne(v: V, i: Int): Path[V] = new Path(this + (v -> i))
// with the companion object below
def addOne(v: V, i: Int): Path[V] = this + (v -> i)
// other methods
}

// this companion object is not strictly necessary, but is useful:
object Path {
implicit def map2path[V](map: Map[V, Int]): Path[V] = new Path(map)
}

这消除了组合方法的尴尬,允许您将 Path 视为 Map:

scala> new Path(Map("a" -> 1)) + ("b" -> 2)
res1: scala.collection.Map[java.lang.String,Int] = Map((a,1), (b,2))

scala> new Path(Map("a" -> 1)).get("a")
res2: Option[Int] = Some(1)

如果您包含从 MapPath 的隐式转换(在 Path 伴随对象中定义),那么您还可以处理 Map 就好像它是一个 Path:

scala> Map("a" -> 1).addOne("b", 2)
res3: Path[java.lang.String] = Map((a,1), (b,2))

有一个类似的 SeqProxy 特征,用于向 Seq 添加行为。

在更一般的情况下,解决方案是使用 pimp my library pattern 。这个related question有一个例子。

关于scala - 扩展内置集合,内置方法的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3472424/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com