Scala 如何修复使用实例上的警告

Scala 如何修复使用实例上的警告,scala,static-code-analysis,Scala,Static Code Analysis,我正在使用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 matchi

我正在使用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!"
}
引述:

抽取器(注意:关于抽取器的更多信息)非致命的
一次性垃圾
。将不匹配致命错误,如
VirtualMachineError
(例如,
OutOfMemoryError
StackOverflowError
VirtualMachineError
)的子类、
ThreadDeath
LinkageError
interruptedeexception
ControlThrowable

您可能希望在代码中使用类似的内容


另一方面,在代码中,您似乎在迭代器中解析对象并将其添加到列表中。这超出了你的问题范围,但我想提出一个小建议

您可能希望研究使用类似以下的方法来实现此目的:

import scala.util.Try

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

实际上,您可能不需要将结果附加到
returnedList
,但我会让您来判断,因为我不知道您的代码。如果您认为这种方法有意义,您可以阅读更多关于
Try
的内容,并了解
collect
方法。

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!"
}
引述:

抽取器(注意:关于抽取器的更多信息)非致命的
一次性垃圾
。将不匹配致命错误,如
VirtualMachineError
(例如,
OutOfMemoryError
StackOverflowError
VirtualMachineError
)的子类、
ThreadDeath
LinkageError
interruptedeexception
ControlThrowable

您可能希望在代码中使用类似的内容


另一方面,在代码中,您似乎在迭代器中解析对象并将其添加到列表中。这超出了你的问题范围,但我想提出一个小建议

您可能希望研究使用类似以下的方法来实现此目的:

import scala.util.Try

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

实际上,您可能不需要将结果附加到
returnedList
,但我会让您来判断,因为我不知道您的代码。如果您认为这种方法有意义,您可以阅读更多关于
Try
的内容,并了解
collect
方法。

阅读模式匹配文档后您尝试了什么?阅读模式匹配文档后您尝试了什么?您的第一个片段正确吗?我认为日志记录和附加到列表应该在while循环中。您的第一个代码片段正确吗?我想我