簡體   English   中英

如何修復有關asInstanceOf使用情況的警告

[英]How to fix a warning on asInstanceOf usage

我正在使用scapegoat進行Scala靜態代碼分析,並且在一段代碼上收到警告。 這是完整的警告

Warning  Use of asInstanceOf  com.sksamuel.scapegoat.inspections.unsafe.AsInstanceOf
asInstanceOf used near cursor.next().asInstanceOf[com.mongodb.casbah.Imports.BasicDBObject]. Consider using pattern matching.

警告指向的行是

obj = cursor.next().asInstanceOf[BasicDBObject]

屬於這段代碼

val q = QueryBuilder.start(fieldName.toString()).is(value)
val cursor = collectionMongo(ARTGROUP_COLLECTION_NAME).find(q.get)
var obj = new BasicDBObject
try {
  while (cursor.hasNext) {
    obj = cursor.next().asInstanceOf[BasicDBObject]
    log.debug(" obj.tostring" + obj.toString())
    retunedList += parseArtGroup(obj)
   }
} catch {
}

如何在上面的代碼中使用模式匹配?

與大多數廣泛使用的語言相比,Scala更加強調類型安全,這就是為什么通常將強制轉換視為代碼氣味的原因。 出於同樣的原因,語言設計人員決定使用類似名稱的isInstanceOf[T]asInstanceOf[T]使轉換變得笨拙,以便在運行時查詢類型並將其轉換。

為了克服這個問題,同時仍然能夠與類型安全的庫進行交互,通常建議使用模式匹配。

這是您使用模式匹配而不是強制轉換的代碼段:

val q = QueryBuilder.start(fieldName.toString()).is(value)
val cursor = collectionMongo(ARTGROUP_COLLECTION_NAME).find(q.get)
var obj = new BasicDBObject
try {
  while (cursor.hasNext) {
    cursor.next() match {                // HERE
      case basicDbObj: BasicDBObject =>  // HERE
        obj = basicDbObj                 // HERE
    }    
    log.debug(" obj.tostring" + obj.toString())
    retunedList += parseArtGroup(obj)
  }
} catch {
}

模式匹配是Scala的一項功能,它允許您將類似的內容應用於其他語言中的switch/case構造,但具有更具表現力的語義。

模式匹配還使您能夠以有意義的方式解構輸入,例如:

List(1, 2, 3, 4) match {
  case head :: tail =>
    println(s"The first element is $head and then comes $tail")
}

值得一提的是,如果您未涵蓋所有可能的情況,則可能會收到其他警告,因為如果不滿足任何匹配子句,則可能會引發MatchError

如果無法完全涵蓋所有可能的情況,則可能需要考慮_標記,該標記象征通配符捕獲所有模式,如以下示例所示:

cursor.next() match {
  case basicDbObj: BasicDBObject =>
    obj = basicDbObj
  case _ => // default case
    ??? // probably some error handling
}

您可以在官方文檔中的Scala 閱讀有關模式匹配的更多信息 這是一個寫得很好的文檔,您將學到很多有關Scala強大功能的知識。

在這一點上,我想補充的一件好事是Scala的try/catch構造使用了一種類似的語法。

try {
  throw new RuntimeException("kaboom :)")
} catch {
  case e: RuntimeException =>
    println(e.getMessage) // prints "kaboom :)"
}

如果不確定要捕獲的內容,Scala附帶了一個非常有用的功能來解構非致命異常:

import scala.util.control.NonFatal

try {
  throw new RuntimeException("kaboom again!")
} catch {
  case NonFatal(e) =>
    println(e.getMessage) // prints "kaboom again!"
}

引用官方文件

非致命Throwables提取器( 請注意:更多有關提取器的信息 )。 將不匹配致命錯誤,例如VirtualMachineError (例如, OutOfMemoryErrorStackOverflowErrorVirtualMachineError子類), ThreadDeathLinkageErrorInterruptedExceptionControlThrowable

您可能需要在代碼中使用與此類似的內容。


另外,在代碼中看起來就像是在迭代器中解析對象並將它們添加到列表中。 它超出了您的問題,但我想提出一個小建議。

您可能需要研究使用類似以下內容的方法:

import scala.util.Try

Try(cursor.collect { case o: BasicDBObject => parseArtGroup(o) }).foreach(returnedList ++= _)

它實際上可能是,你實際上並不需要你的結果追加到的情況下returnedList ,但我會告訴你是法官,我不知道你的代碼。 如果你覺得這種做法是有道理的,你可以閱讀更多的Try 這里 ,了解collect方法在這里

暫無
暫無

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

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