lee*_*777 7 scala lift scala-2.8
我正在尝试将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
Run Code Online (Sandbox Code Playgroud)
最干净的方法是什么?
Itt*_*ayD 10
scala> import collection.breakOut
import collection.breakOut
scala> def foo: NodeSeq = data.map { s => <x>{s}</x> }(breakOut)
foo: scala.xml.NodeSeq
Run Code Online (Sandbox Code Playgroud)
方法映射实际上有两个参数列表.第一个接受您传递的函数.第二个接受CanBuildFrom对象,该对象用于创建构建器,然后构建返回序列.这个参数是隐含的,所以通常编译器会为你填充它.它接受3种类型参数:From,T,To.有几个pref implicits(包括在对象NodeSeq中),但它们都不匹配From = Array,T = Node,To = NodeSeq.
breakOut解决了这个问题:它是一个泛型方法,通过搜索隐式CanBuildFrom [Nothing,T,To]来返回CanBuildFrom实例.根据隐式搜索规则,任何匹配T,To且具有From> Nothing的CanBuildFrom都是可接受的.在这种情况下:对象Array中的canBuildFrom
我只是将map
输出转换为序列(假设Seq[Node]
是超类NodeSeq
)
scala> def foo: NodeSeq = data.map { s => <x>{s}</x> } toSeq
foo: scala.xml.NodeSeq
Run Code Online (Sandbox Code Playgroud)
或使用foldLeft
而不是map
scala> def foo: NodeSeq = (Seq[Node]() /: data) {(seq, node)=> seq ++ <x>{node}</x>}
foo: scala.xml.NodeSeq
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4068 次 |
最近记录: |