Scala集合类型之间的隐式转换

时间:2011-01-13 00:13:36

标签: xml scala dom4j

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

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。如果我传递一个List,我也会得到一个Traversable。所以我假设转换应该以某种方式进行参数化。

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

2 个答案:

答案 0 :(得分: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/>)

这就是你追求的目标?

答案 1 :(得分:1)

我认为这可能会造成太多牵连。特别是你可以在地图中使用转换器方法

val listOfElements = listOfElems map elemToElement(_)

我认为你所要达到的水平简洁性正在进行混淆。我会创建一个转换器层,只在其中一个表示中工作,以防止事情变得混乱。