簡體   English   中英

Scala中的模式匹配或isInstanceOf

[英]Pattern matching or isInstanceOf in Scala

假設我有以下類層次結構:

trait A; class A1 extends A; class A2 extends A

現在我需要過濾List[A] A1實例。 我使用模式匹配或isInstanceOf

 as.filter(cond(_){case _: A1 => true}) // use pattern matching
 as.filter(_.isInstanceOf[A1]) // use isInstanceOf

它的工作原理是否一樣? 你更喜歡什么?

你為什么不用收集? 這具有額外的好處,即返回的列表將是正確的類型(List [A1]而不是List [A])

val a1s = as.collect { case x:A1 => x }

雖然接受的答案會給你一個很好的建議,但請注意scala中的asInstanceOf與使用isInstanceOf結合asInstanceOf沒有什么不同。 這兩個例子大致相同:

def foo(x: Any) = x match {
   case s: String = println(s"$s is a String)
   case _ => println("something else")
}

def foo(x: Any) = x match {
   case _ if x.isInstanceOf[String] => println(s${x.asInstanceOf[String]} is a String)
   case _ => println("something else")
}

因此,在您的具體示例中,您使用的兩個中的哪一個並不重要:您總是會做某種向下轉換,這通常是可以避免的。

看看第二個版本是如何更加丑陋,因此更合適,因為你在功能語言中做了一件“丑陋”的事情。

所以,我會去

val a1s = as.collect{case x if x.isInstanceOf[A1] => x.asInstanceOf[A1]}

丑陋的東西應該看起來很難看。

它的工作原理是否一樣?

將生成相同的答案,但在每種情況下將發出不同的代碼,如您所料。

您可以檢查在每種情況下生成的IL,如下所示。 使用以下內容創建“ test.scala ”文件:

import PartialFunction.cond

trait A; class A1 extends A; class A2 extends A

class Filterer {
  def filter1(as: List[A]) =
    as.filter(cond(_){case _: A1 => true}) // use pattern matching

  def filter2(as: List[A]) =
    as.filter(_.isInstanceOf[A1]) // use isInstanceOf
}

然后運行:

scalac test.scala

要檢查as.filter(cond(_){case _: A1 => true})版本的IL,請執行

javap -c 'Filterer$$anonfun$filter1$1'
javap -c 'Filterer$$anonfun$filter1$1$$anonfun$apply$1'

然后檢查as.filter(_.isInstanceOf[A1])版本的IL,你可以做

javap -c 'Filterer$$anonfun$filter2$1'

cond ”版本使用更多中間值,並實例化更多表示所涉及的額外匿名函數的對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM