2014-12-02 28 views
0

我一直在試圖想出一個函數來檢查參數是否爲運行時給出的類型。檢查arg1是否爲arg2實例的函數,如Scala中的isInstanceOf(a,A)

考慮功能is(以下簡稱「是類」),在下面的例子:

object TestClass { 
     abstract class P() 
     case class A() extends P 
     case class B() extends P 
     // ... 
     case class Z() extends P 

     def is[VALUE,TYPE](value:VALUE, T:TYPE): Boolean = { 
      value match { 
       case T => true 
       case _ => false 
      } 
     } 

     def main(args: Array[String]) { 
      val a = new A() 
      val b = new B() 

      println(a.isInstanceOf[A]) // true 
      println(is(a, A)) // false 
      println(is(b, B)) // false 
     } 
    } 

我讀過有關ClassTag和的getClass,但我是新來的Scala和不能正確地應用它們,它似乎。 is應該如何實現全部println -lines返回true

回答

0

你檢查對T,這將是同伴對象的AB - 這可能是更容易理解發生了什麼事情,如果你使用非case類。

糾正你會發現它總是返回true的代碼,一個警告,該模式沒有被選中,由於擦除後:

def is[TYPE](value: Any): Boolean = value match { 
    case t: TYPE => true 
    case _ => false 
} 

解決這個問題的常用方法是使用ClassTag作爲一個模式:

def is[TYPE](value: Any)(implicit tag: ClassTag[TYPE]): Boolean = value match { 
    case tag(_) => true 
    case _ => false 
} 

注意,這隻會匹配運行時,刪除類,所以你會得到驚人的答案泛型類型:

is[List[Int]](List("abc")) //true 

如果你想要一個更一般的解決方案,你可以看看Shapeless type-safe extractors

+0

很好地工作,謝謝你的解釋! – sao 2014-12-02 15:53:15

相關問題