2012-09-27 54 views
2

說你給出的List[Class[_ <: Base]]一個實例,並說,許多類擴展Base測試,如果一個給定的實例是Scala(子)類的指定類的

class A extends Base 
class B extends Base 
class C extends A 

等」 ...
現在,給定的列表可能只包含一些類。例如:val classes = classOf[A] :: Nil,好吧,我如何測試當我得到一個實例0123'如果它的類是在列表中找到的類型,或者如果它是列表中的類的子類?例如,你將如何實現:
def testClass(class : List[Class[_ <: Base]], instance : Base) : Boolean
時:

val classes = classOf[A] :: Nil 
testClass(classes, new A) // should return true 
testClass(classes, new B) // should return false 
testClass(classes, new C) // should return true 

使用案例:
我試圖寫一個通用重試模式,即得到了一些代碼,這是非常容易出錯,我想重試執行一些次數的最大嘗試,當每次失敗時,它應該執行一些「等待」方法。
例如

retryRequest({ 
    //Some code that throws exceptions 
}, classOf[SomeException] :: classOf[SomeOtherException] :: Nil, 
100, {Thread.sleep(5000)}) 

好這個工程確定,但它不會測試對於給定的異常的子類:

def retryRequest(req : => Unit, validExceptions : List[Class[_ <: java.lang.Throwable]], tries : Int, waitMethod : => Unit) { 
    var keepTrying = false 
    var tryCount = 0 
    do{ 
     try{ 
      logger.debug("retryRequest, try #" + tryCount) 
      keepTrying = false 
      req 
     }catch{ 
      case ex if(tryCount >= tries && validExceptions.contains(ex.getClass)) => { 
       throw new MaxTriesReachedException("tried for " + tryCount + "times, but no luck. " + 
                "you may want to try ommitting generic exceptions types from the given list.") 
      } 
      case ex if (validExceptions.contains(ex.getClass)) => { 
       logger.debug("intercepted " + ex.toString) 
       tryCount += 1 
       keepTrying = true 
       waitMethod 
      } 
     } 
    }while(keepTrying) 
} 

我會真的想取代:

validExceptions.contains(ex.getClass) 

的東西,如:

validExceptions.exists(exClass => ex.isInstanceOf[exClass]) //won't compile 

是否有可能?怎麼樣?

+0

也許這個問題有幫助嗎? http://stackoverflow.com/questions/2603003/operator-in-scala – Jan

回答

9

更簡單的方法是使用util.control.Exception

def retryRequest(req: => Unit, 
        validExceptions: List[Class[_ <: Throwable]], 
        tries: Int, 
        waitMethod: => Unit): Unit = 
    (Exception.catching(validExceptions:_*) withApply { e => 
     waitMethod 
     if (tries > 1) retryRequest(req, validExceptions, tries - 1, waitMethod) 
    }) { req } 

    retryRequest({ println("a"); throw new Exception }, 
       List(classOf[Exception]), 
       3, 
       Thread.sleep(100)) 

簡而言之:withApply需要,處理時的情況下關閉拋出傳遞給catching的例外之一。在我們的例子中,我們簡單地稱自己爲遞歸(假設重試次數很少,我認爲這不是問題)。

相關問題