val myArray = Array("1", "2")
val error = myArray(5)//throws an ArrayOutOfBoundsException
myArray
没有固定的大小,这就解释了为什么可能会在上面的第二行执行调用。
首先,我从未真正理解将error handling
用于预期错误的原因。我认为这种做法是不好的,因为编码技巧不好或倾向于懒惰,我是错误的吗?
处理上述情况的最佳方法是什么?
Option
; Try
或Either
; try-catch
块。答案 0 :(得分:1)
使用arr.lift
(标准库中提供)返回Option
而不是抛出异常。
如果不使用safely
尝试访问元素safely
,以避免在代码中间意外抛出异常。
implicit class ArrUtils[T](arr: Array[T]) {
import scala.util.Try
def safely(index: Int): Option[T] = Try(arr(index)).toOption
}
用法:
arr.safely(4)
<强> REPL 强>
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)
答案 1 :(得分:1)
如果索引myArray
有时会出错,那么听起来Option
就好了。
myArray.lift(1) // Option[String] = Some(2)
myArray.lift(5) // Option[String] = None
您可以使用Try()
,但如果您已经知道错误是什么并且您对捕获或报告它不感兴趣,为什么还要费心呢?
答案 2 :(得分:1)
Scala提供了一组丰富的集合操作,这些操作通过ArrayOps
隐式转换应用于阵列。这样,我们就可以在数组上使用combinators
,例如map
,flatMap
,take
,drop
,....而不是按索引寻址元素。
我在解析类似CSV的数据时经常看到的一个例子(在Spark中):
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))}
如果我们使用monadic构造来组合对某些资源的访问,请对应用程序流使用适合的提升错误方式: 例如想象一下,我们正在从某个存储库中检索用户首选项,我们想要第一个:
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
(甚至更好,应用建议#1):
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
作为一般指导:使用principle of least power。
如果可能,请使用无错误的组合器:= array.drop(4).take(1)
如果重要的是有元素,请使用Option
如果我们需要保留找不到元素的原因,请使用Try
。
让节目的类型和背景指导您。