我正在尝试将Lift应用程序集成到一些现有的Java代码中。在我的一个片段中,我有一个Java对象Array,我需要将它映射到NodeSeq。我可以获得一个节点数组,但不能获得NodeSeq。 (至少,不是以非常实用的方式)。
import scala.xml.NodeSeq
// pretend this is code I can't do anything about
val data = Array("one", "two", "three")
// this is the function I need to write
def foo: NodeSeq = data.map { s => <x>{s}</x> }
// ^
// error: type mismatch;
// found : Array[scala.xml.Elem]
// required: scala.xml.NodeSeq
最干净的方法是什么?
答案 0 :(得分:10)
scala> import collection.breakOut
import collection.breakOut
scala> def foo: NodeSeq = data.map { s => <x>{s}</x> }(breakOut)
foo: scala.xml.NodeSeq
方法图实际上有两个参数列表。第一个接受您传递的函数。第二个接受CanBuildFrom对象,该对象用于创建构建器,然后构建返回序列。这个参数是隐含的,所以通常编译器会为你填充它。它接受3种类型参数:From,T,To。有几个pref implicits(包括在对象NodeSeq中),但它们都不匹配From = Array,T = Node,To = NodeSeq。
breakOut解决了这个问题:它是一个泛型方法,它通过搜索隐式CanBuildFrom [Nothing,T,To]来返回CanBuildFrom实例。根据隐式搜索规则,任何匹配T,To和具有From&gt;的CanBuildFrom。什么都不能接受。在这种情况下:对象数组中的canBuildFrom
答案 1 :(得分:8)
我只是将map
输出转换为序列(假设Seq[Node]
是超级类NodeSeq
)
scala> def foo: NodeSeq = data.map { s => <x>{s}</x> } toSeq
foo: scala.xml.NodeSeq
或使用foldLeft
代替map
scala> def foo: NodeSeq = (Seq[Node]() /: data) {(seq, node)=> seq ++ <x>{node}</x>}
foo: scala.xml.NodeSeq
答案 2 :(得分:2)
您正在NodeSeq配套对象上寻找此方法。
NodeSeq.fromSeq(s: Seq[Node])