Scala 将选项与.map()和.getOrElse()一起使用

Scala 将选项与.map()和.getOrElse()一起使用,scala,Scala,我试图从给定键的映射[String,String]中读取一个值。 该键|值是可选的,因为它可能不存在 因此,我想使用Option,然后使用下面的map&getOrElse来写入值(如果有),或者在不存在的情况下将其设置为默认值 val endpoint:String = Option(config.getString("endpoint")) .map(_.value()) .getOrElse() 上述代码因“无法从此位置访问符号值”而失败 配置是一个映射[字符串,对象] g

我试图从给定键的
映射[String,String]
中读取一个值。 该键|值是可选的,因为它可能不存在 因此,我想使用Option,然后使用下面的
map
&
getOrElse
来写入值(如果有),或者在不存在的情况下将其设置为默认值

val endpoint:String = Option(config.getString("endpoint"))
    .map(_.value())
    .getOrElse()
上述代码因“无法从此位置访问符号值”而失败

配置是一个
映射[字符串,对象]

getString
是config上的一个方法,它接受键并返回值

public String getString(String key){
    <...returns value...>
}
你知道这有什么问题吗,或者怎么解决? 更好的写作方法


更新:我需要提到配置是导入的Java库中的一个对象。我不确定这是否有区别

如果我正确理解了您的问题,
config.getString
将在密钥不存在时引发异常。在这种情况下,在
Option()
中包装调用无助于捕获该异常:您应该改为在
Try
中包装调用,并将其转换为
选项

Try[String]
表示一种计算,它可以成功并成为
成功(String)
,也可以失败并导致
失败(thrownException)
。如果您熟悉
选项
,这与
部分
的两种可能性非常相似,只是
故障
将包装异常,以便您知道问题的原因。
Try(someComputation)
方法将为您执行以下操作:

try {
    Success(someComputation)
} catch {
    case ex: Exception => Failure(ex)
}
第二件事是当你没有价值时,你真正想要发生的事情。一个明智的想法是提供一个默认配置,这就是
getOrElse
的目的:如果不给它默认值,就不能使用它

以下是一个例子:

val endpoint = Try(config.getString("endpoint"))
    .toOption
    .getOrElse("your_default_value")
我们可以做得更好:现在我们使用
Try
捕获异常,如果我们要立即访问该值,则无需转换为
选项

val endpoint = Try(config.getString("endpoint")).getOrElse("your_default_value")

您可以从这样的贴图中获取值

val m: Map[String, String] = Map("foo" -> "bar")
val res  = m.get("foo").getOrElse("N.A") 
val res2 = m.getOrElse("foo", "N.A") // same as above but cleaner
但是,如果您想使用模式匹配:

val o: Option[String] = m.get("foo")
val res: String = o match { 
  case Some(value) => value
  case None => "N.A"
}
最后,是处理从配置读取的安全方法

val endpoint:String = config.getString("endpoint") // this can return null
val endpoint: Option[String] = Option(config.getString("endpoint")) // this will return None if endpoint is not found
我怀疑config对象甚至可能有这样一个方法

val endpoint: Option[String] = config.getStringOpt("endpoint")
然后可以使用模式匹配来提取选项中的值。或者是众多组合词中的一个
map
flatMap
fold

val endPoint = Option(config.getString("endpoint"))

def callEndPoint(endPoint: String): Future[Result] = ??? // calls endpoint

endPoint match { 
  case Some(ep) => callEndPoint(ep)
  case None     => Future.failed(new NoSuchElementException("End point not found"))
}


当我尝试第一个示例时,使用.toOptionMap(u.value)时,我得到了与代码相同的错误——“值在此位置不可访问”。不知何故,价值是未知的。奇怪的然而,如果我尝试第二种方法,这似乎工作得很好。当我击中。在映射()的内部之后,弹出的intellisense使我认为我正在处理一个字符串,因为我看到了charAt、chars等方法…。我希望在弦上看到的东西。所以,这就是找不到值的原因,因为字符串上没有值。但是为什么呢?我不知道你从哪里得到的
.map(u.value)
。我们需要更多关于
config
的信息,它的确切类型是什么?
val endPoint = Option(config.getString("endpoint"))

def callEndPoint(endPoint: String): Future[Result] = ??? // calls endpoint

endPoint match { 
  case Some(ep) => callEndPoint(ep)
  case None     => Future.failed(new NoSuchElementException("End point not found"))
}
 val foo = endPoint.map(callEndPoint).getOrElse(Future.failed(new NoSuchElement...))