5

我想在 Scala XML Elem 对象和 XML 元素的另一种表示形式之间进行隐式转换,在我的例子中是 dom4j 元素。我写了以下隐式转换:

implicit def elemToElement(e: Elem): Element = ... do conversion here ...
implicit def elementToElem(e: Element): Elem = ... do conversion here ...

到目前为止一切顺利,这行得通。

现在我还需要所述元素的集合来转换两种方式。首先,我绝对需要编写额外的转换方法吗?如果我不这样做,事情似乎就不起作用了。

我试图写以下内容:

implicit def elemTToElementT(t: Traversable[Elem]) = t map (elemToElement(_))
implicit def elementTToElemT(t: Traversable[Element]) = t map (elementToElem(_))

这看起来不太理想,因为如果转换方法采用 Traversable,那么它也会返回一个 Traversable。如果我通过一个列表,我也会得到一个 Traversable。所以我认为转换应该以某种方式参数化。

那么为了尽可能通用而编写这些转换的标准方法是什么?

4

2 回答 2

2

这不是微不足道的,所以为了得到你想要的东西,我认为你必须更深入一点。这篇文章解释了很多关于 scala 集合是如何工作的(读起来也很有趣):http ://www.artima.com/scalazine/articles/scala_collections_architecture.html

您基本上是在尝试与 List.map(...) (或具有实现的 TraversableLike )和类似方法做相同的事情....仅使用隐式转换。

更新:

我开始对此进行一些试验,并根据 TraversableLike.map(...) 的作用编写了一个转换。但是我发现即使没有它也能正常工作。似乎 Scala 开箱即用地支持它(至少在我的机器上 :-)):

case class Element(e: Elem)
implicit def elemToElement(e: Elem): Element = Element(e)
implicit def elementToElem(e: Element): Elem = e.e

val a: List[Element] = List(<a/>, <b/>, <c/>)
val b: List[Elem] = List(Element(<a/>), Element(<b/>), Element(<c/>))
val c: Set[Element] = Set(<a/>, <b/>, <c/>)

这就是你所追求的?

于 2011-01-13T08:25:20.933 回答
1

我认为这可能隐含得太远了。特别是因为您可以在地图中使用转换器方法

val listOfElements = listOfElems map elemToElement(_)

我认为你所追求的层次简洁正在变得模糊。我将创建一个转换器层并仅使用其中一种表示形式,以防止事情变得混乱。

于 2011-01-13T01:44:06.127 回答