2012-06-27 20 views
11
sealed class A 
class B1 extends A  
class B2 extends A 

假設我們有A類的對象的列表: VAL l:列出[A] =列表何時使用isInstanceOf以及何時使用匹配大小寫語句(在Scala中)?

而且我們希望以濾除(新B1,新B2,新B1,新B1)的B1型元素。 然後,我們需要一個謂語,可以使用以下兩種選擇:

l.filter(_.isInstanceOf[B1]) 

或者

l.filter(_ match {case b: B1 => true; case _ => false}) 

就個人而言,我喜歡的第一個進場,但我經常看,應該使用match-case語句的更多經常(因爲我不知道的原因)。

因此,問題是:是否存在使用isInstanceOf而不是match-case聲明的缺點?什麼時候應該使用哪種方法(以及在這裏使用哪種方法以及爲什麼)?

回答

17

可以篩選這樣的:

l.collect{ case x: B1 => x } 

也就是說更具可讀性,海事組織。

+3

並在末尾給出更窄的類型('List [B1]')。 –

+0

看起來更具可讀性,謝謝。但是這個聲明中的默認情況是什麼?我在哪裏可以閱讀有關此快捷方式案例聲明的更多背景信息以及它如何使用? –

+0

@JohnThreepwood看看[這篇文章](http://ochafik.com/blog/?p=393)。這不是最好的,但仍然非常好,「收集的原因」。簡而言之,收集就像地圖一樣,但僅對那些爲傳遞給此方法的*(部分)*函數定義的值進行工作。在這種情況下,Scala的模式匹配是在[PartialFunction]之上完成的(http://stackoverflow.com/questions/5668053/scala-partial-functions)。另外,您需要使用大括號。 –

7

有沒有區別

貓t.scala:

class A { 
    def x(o: AnyRef) = o.isInstanceOf[A] 
    def y(o: AnyRef) = o match { 
    case s: A => true 
    case _ => false 
    } 
} 

$ scalac -print t.scala

[[syntax trees at end of cleanup]]// Scala source: t.scala 
package <empty> { 
    class A extends java.lang.Object with ScalaObject { 
    def x(o: java.lang.Object): Boolean = o.$isInstanceOf[A](); 
    def y(o: java.lang.Object): Boolean = { 
     <synthetic> val temp1: java.lang.Object = o; 
     temp1.$isInstanceOf[A]() 
    }; 
    def this(): A = { 
     A.super.this(); 
    () 
    } 
    } 
} 
+0

非常好,謝謝你的背景信息scala編譯器會做什麼。 –

9

match-case的好處是,你不如果您想對其執行操作(取決於其較窄的類型),則必須投射該對象。

在下面的代碼片段,使用isInstanceOf似乎是罰款,因爲你不執行這樣的操作:

if (obj.isInstanceOf[A]) println(obj) 

然而,如果你做到以下幾點:

if (obj.isInstanceOf[A]) { 
    val a = obj.asInstanceOf[A] 
    println(a.someField) // someField is declared by A 
} 

那麼我d贊成使用match-case

obj match { 
    case a: A => println(a.someField) 
    case _ => 
} 

它有點惱人荷蘭國際集團,你必須包括「否則」 - 案例,但使用collect(如由OM-NOM-NOM暗示)可以幫助,至少如果你有收集工作由SEQ繼承:

collectionOfObj.collect{ case a: A => a}.foreach(println(_.someField)) 
+0

謝謝你的好例子,非常好。 –

9

有沒有問題使用isInstanceOf,只要你不使用asInstanceOf

使用兩者的代碼是脆弱的,因爲檢查和鑄造是單獨的動作,而使用匹配你有一個單一的動作。

+0

謝謝你的提示,我會留意的。 –

相關問題