繁体   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