Scala 处理基本数组错误的最佳方法

Scala 处理基本数组错误的最佳方法,scala,error-handling,Scala,Error Handling,myArray没有固定的大小,这解释了为什么在上面的第二行执行这样的调用可能会发生 首先,我从未真正理解使用错误处理处理预期错误的原因。我认为这种做法是不好的,是因为编码技巧差还是倾向于懒惰? 处理上述案件的最佳方式是什么 我倾向于:基本实现(条件),以防止访问所描述的数据 使用选项 使用尝试或其中一种 使用try catch块 使用arr.lift(在标准库中提供),它返回选项而不是引发异常 如果不安全地使用 尝试安全地访问元素,,以避免在代码中间意外抛出异常 val myArray = A

myArray
没有固定的大小,这解释了为什么在上面的第二行执行这样的调用可能会发生

首先,我从未真正理解使用
错误处理
处理预期错误的原因。我认为这种做法是不好的,是因为编码技巧差还是倾向于懒惰? 处理上述案件的最佳方式是什么

  • 我倾向于:基本实现(条件),以防止访问所描述的数据
  • 使用
    选项
  • 使用
    尝试
    其中一种
  • 使用
    try catch
使用
arr.lift
(在标准库中提供),它返回
选项而不是引发异常

如果不安全地使用

尝试安全地访问元素
,以避免在代码中间意外抛出异常

val myArray = Array("1", "2")
val error = myArray(5)//throws an ArrayOutOfBoundsException
用法:

implicit class ArrUtils[T](arr: Array[T]) {
   import scala.util.Try
   def safely(index: Int): Option[T] = Try(arr(index)).toOption
}
REPL

arr.safely(4)

如果可以预期索引
myArray
有时会出错,那么听起来
Option
将是一个不错的选择

scala> val arr = Array(1, 2, 3)
arr: Array[Int] = Array(1, 2, 3)

scala> implicit class ArrUtils[T](arr: Array[T]) {
   import scala.util.Try
   def safely(index: Int): Option[T] = Try(arr(index)).toOption
  }
defined class ArrUtils

scala> arr.safely(4)
res5: Option[Int] = None

scala> arr.safely(1)
res6: Option[Int] = Some(2)
您可以使用
Try()
,但是如果您已经知道错误是什么,并且对捕获或报告它不感兴趣,为什么还要麻烦呢?

1避免通过索引寻址元素 Scala提供了一组丰富的收集操作,这些操作通过
ArrayOps
隐式转换应用于数组。这让我们可以使用
组合词
,如
map
flatMap
take
drop
。。。。在数组上,而不是按索引寻址元素

2防止进入超出范围 我在解析类似CSV的数据时经常看到的一个示例(在Spark中):

3使用符合当前上下文的检查 如果我们使用一元结构来组合对某些资源的访问,请使用适当的方法将错误提升到应用程序流: e、 g.假设我们正在从某个存储库中检索用户首选项,我们想要第一个:

选项
def getUserById(id:id):选项[User]
def getPreferences(用户:用户):选项[数组[首选项]]
val topPreference=for{

用户:不清楚您的要求是什么。如果您想使用
myArray(5),您是否提到了
ArrayOutOfBoundsException
的潜力
?如果是这样,如何处理将取决于上下文。您可以始终检查大小并避免异常。对于任何可能引发异常的代码,您应该将其包装在
Try
中。然后您可以使用该
Try
执行任何操作。
myArray.lift(1)  // Option[String] = Some(2)
myArray.lift(5)  // Option[String] = None
case class Record(id:String, name: String, address:String)
val RecordSize = 3
val csvData = // some comma separated data
val records = csvData.map(line => line.split(","))
                     .collect{case arr if (arr.size == RecordSize) => 
                              Record(arr(0), arr(1), arr(2))}
def getUserById(id:ID):Option[User]
def getPreferences(user:User) : Option[Array[Preferences]]

val topPreference = for {
      user <- userById(id)
      preferences <- getPreferences(user)
      topPreference <- preferences.lift(0)
   } yield topPreference
val topPreference = for {
      user <- userById(id)
      preferences <- getPreferences(user)
      topPreference <- preferences.headOption
   } yield topPreference
def getUserById(id:ID): Try[User]
def getPreferences(user:User) : Try[Array[Preferences]]
val topPreference = for {
      user <- userById(id)
      preferences <- getPreferences(user)
      topPreference <- Try(preferences(0))
   } yield topPreference