2011-06-16 29 views
7

我有一個API(來自第三方Java庫),看起來像:如何在Scala List中投射每個元素?

public List<?> getByXPath(String xpathExpr) 
一個叫做れ

我想要做的事類中定義

想了解Scala的列表,其中每個產品的指定的類型:

val txtNodes: List[DomText] = node.getByXPath(xpath).toList 

但編譯器給出錯誤:類型不匹配。

這個問題的解決方案是什麼?

+0

這需要'進口scala.collection.JavaConversions._'編譯。 – Lutz 2011-06-16 15:05:26

回答

13

您需要轉換列表中的每個元素,以證明它們都具有所需的類型。 進行遍歷時,你可以這樣做,只是,例如

node.getByXPath(xpath).map{case d: DomText => d}.toList 

node.getByXPath(xpath).map(_.asInstanceOf[DomText]).toList 

哪個演員適合你更好的寫作。

您也可以施放清單node.getByXPath(xPath).toList.asInstanceOf[List[DomText]],但是您會收到警告,因爲此類轉換由於類型擦除而沒有進行任何檢查(就像在java中一樣)。

+0

我相信你上面的兩個例子會給不同於DomText元素的列表提供不同的行爲,第一個例子默默地放棄它們,第二個例子拋出一個運行時異常。如果是這樣,他們之間的選擇將涉及更多的個人偏好。 – 2011-06-16 18:59:58

+0

他們沒有。 map採用Function參數,而不是PartialFunction,如果函數失敗,它將失敗。收集如@Alois Cochard所介紹的答案將過濾。但是我的兩個變體在引發異常時有所不同,MatchError與模式匹配,ClassCastException與asInstanceOf。 – 2011-06-16 20:14:27

9

由於斯卡拉2.8,你可以用 '收集':

scala> "hi" :: 1 :: "world" :: 4 :: Nil collect {case s:String => s} 
res13: List[String] = List(hi, world) 

來源: http://daily-scala.blogspot.com/2010/04/filter-with-flatmap-or-collect.html

+1

不錯,我一直忘記這一個。但是有一個區別。正如你的例子所證明的,collect會過濾出不能被鑄造的元素。另一方面,如果存在這樣的元素,則地圖將失敗。在所有演員都可以的情況下,這並不重要。當人們不確定演員是否確定時,必須決定是否需要過濾失敗。 – 2011-06-16 14:32:40

+0

@didierd你是完全正確的,在我提到的博客帖子的評論中有一個很好的例子,顯示瞭如何以慣用的方式處理演員異常! – 2011-06-17 06:14:49

相關問題