我有一个API(来自第三方java库),如下所示:
public List<?> getByXPath(String xpathExpr)
在名为DomNode
的类上定义我在scala函数中尝试这个:
1: def removeChild(node: DomNode, xpath: String) {
2: val lst: List[?] = node.getByXPath(xpath)
3: val child: DomNode = lst(0)
4: child.getParentNode().removeChild(child)
}
但它不能在scala中编译。我在第2行得到错误。
根据答案,我修改了它,现在它是:
1: def removeChild(node: DomNode, xpath: String) {
2: val lst = node.getByXPath(xpath)
3: val child = lst(0).asInstanceOf[DomNode]
4: child.getParentNode().removeChild(child)
}
现在我在第3行得到错误:java.util.List类型的lst [?0]不带参数
我也试过了val lst: List[_] = node.getByXPath(xpath)
,但这在同一行上给了我错误:
type mismatch;
found : java.util.List[?0] where type ?0
required: scala.List[_]
所以我仍然被卡住了。
答案 0 :(得分:5)
在第3行重新判断你的错误:记住它是一个Java列表,而不是Scala列表,所以试试
val child = lst.get(0).asInstanceOf[DomNode]
答案 1 :(得分:2)
以下是您的代码出了什么问题:
def removeChild(node: DomNode, xpath: String) {
val lst: List[?] = node.getByXPath(xpath)
/* ^^^^^^^ This probably refers to scala.collection.immutable.List,
which is a totally different type from the
java.util.List that getByXPath returns.*/
/* Also, the ? needs to be changed into an _ in Scala */
val child: DomNode = lst(0)
/* Two problems here: First, java.util.List won't support indexing
with parentheses. Second, you need to typecast the result to get a
DomNode. */
child.getParentNode().removeChild(child)
}
以下是更正后的版本:
import scala.collection.JavaConversions._
def removeChild(node:DomNode, xpath:String) {
val lst:scala.collection.Seq[_] = node.getByXPath(xpath)
/* triggers an implicit conversion that wraps the Java List in a Scala Seq */
val child: DomNode = lst(0).asInstanceOf[DomNode]
child.getParentNode().removeChild(child)
}
(省略类型注释仍然有效 - 而不是在分配val lst
时导致转换,当您尝试调用lst(0)
时,它会导致转换。)
另一个未转换为Scala Seq
的更正版本:
def removeChild(node:DomNode, xpath:String) {
val lst:java.util.List[_] = node.getByXPath(xpath)
/* you can remove the type annotation here, but I left it in
for pedagogical purposes */
val child: DomNode = lst.get(0).asInstanceOf[DomNode]
child.getParentNode().removeChild(child)
}
答案 2 :(得分:1)
这应该有效:
val lst: java.util.List[_] = node.getByXPath(xpath)
答案 3 :(得分:1)
以下对我有用:
val arr = DomNode.getByXPath("foo").toArray
val child = lst(0).asInstanceOf[DomNode]
显然没有将通配符Java列表隐式转换为Scala列表,因此,您创建的val lst
属于java.util.list
类型,当然没有应用方法。我通过从列表中创建一个Scala数组来解决这个问题。
答案 4 :(得分:0)
这是我的看法:
def removeChild(node: DomNode, xpath: String) {
// Let type inference do the work for you
// val lst: List[?] = node.getByXPath(xpath)
val lst = node.getByXPath(xpath)
// Also, do not confuse Java's and Scala's collections
// val child: DomNode = lst(0)
val child = lst.get(0)
// Finally, since you do not have a static guarantee of the type,
// match on it
// child.getParentNode().removeChild(child)
child match {
case domNode: DomNode => domNode.getParentNode().removeChild(domNode)
case _ =>
}
}