如何使用Option monad?我正在浏览scala api并且有一个例子(我的意思是第二个),
由于理解的工作原理,如果从request.getParameter返回None,则整个表达式将导致None
但是当我尝试这段代码时:
val upper = for {
name <- None //request.getParameter("name")
trimmed <- Some(name.trim)
upper <- Some(trimmed.toUpperCase) if trimmed.length != 0
} yield upper
println(upper.getOrElse(""))
Run Code Online (Sandbox Code Playgroud)
我收到编译错误.这应该怎么样?
是否有可能Option[Map[String,String]]一次匹配某些键(例如没有嵌套匹配)?
以下片段是现在的样子:
val myOption:Option[Map[String,String]] = ...
myOption match {
case Some(params) =>
params get(key) match {
case Some(value) => Ok(value)
case None => BadRequest
case None => BadRequest
}
Run Code Online (Sandbox Code Playgroud) 当列表非空时,是否有一种紧凑的方式将列表的头部作为一个列表,否则得到无?
这就是我目前正在做的事情,
val ms = moves.filter { ...some predicate... }
if (ms.nonEmpty) Some(ms.head) else None
Run Code Online (Sandbox Code Playgroud) 我想要这样的东西:
private val cachedResponse = mutable.Option.empty[A]
def get: A = cachedResponse getOrElseUpdate db.findModel()
def update: Unit = {
db.updateModel
cachedResponse.empty() // set it to None/Option.empty
}
Run Code Online (Sandbox Code Playgroud)
我不是在寻找像这样的泛型基于HashMap的memoization .我尝试使用a实现它,var Option[A]但它对我来说看起来不是很惯用:
private var cachedResponse: Option[A] = None
def get: A = cachedResponse getOrElse {
cachedResponse = Option(db.findModel())
cachedResponse.get
}
def update: Unit = {
db.updateModel
cachedResponse = None
}
Run Code Online (Sandbox Code Playgroud) 我正在映射HBase表,每个HBase行生成一个RDD元素.但是,有时行有坏数据(在解析代码中抛出NullPointerException),在这种情况下我只想跳过它.
我有我的初始映射器返回一个Option表示它返回0或1个元素,然后筛选Some,然后获取包含的值:
// myRDD is RDD[(ImmutableBytesWritable, Result)]
val output = myRDD.
map( tuple => getData(tuple._2) ).
filter( {case Some(y) => true; case None => false} ).
map( _.get ).
// ... more RDD operations with the good data
def getData(r: Result) = {
val key = r.getRow
var id = "(unk)"
var x = -1L
try {
id = Bytes.toString(key, 0, 11)
x = Long.MaxValue - Bytes.toLong(key, 11)
// ... more code that might throw exceptions …Run Code Online (Sandbox Code Playgroud) 我是Scala的新手,偶然发现了一个小问题,这个问题一直困扰着我。假设有一些带有默认参数的方法
def foo(v: Any = "default"): String = s"called with parameter '$v'"
Run Code Online (Sandbox Code Playgroud)
和一个Option val opt: Option[String]。如何使用选项值(如果已定义)或默认参数调用此方法?我的意思是尽管有明显的解决方案
val result = if (opt.isDefined)
from.here.to.foo(opt.get)
else
from.here.to.foo()
Run Code Online (Sandbox Code Playgroud)
并且不得不用对象链(可能很长)键入两次该方法?更不用说具有多个可选/默认参数了...
我所能想到的就是无助的帮手
def definedOrDefault[A, B](opt: Option[A], f0: => B, f1: A => B): B =
if (opt.isDefined) f1(opt.get) else f0
Run Code Online (Sandbox Code Playgroud)
但是当无法在高阶函数中提及默认参数时,就是这样。让我想起了Java过去的糟糕时光,其中方法重载会产生相同的问题。
我有一个变量,obj: Option[MyObject]并希望从中提取多个变量 - 如果未设置该对象,则应使用默认值.
目前我这样做:
val var1 = obj match {
case Some(o) => e.var1
case _ => "default1"
}
val var2 = obj match {
case Some(o) => e.var2
case _ => "default2"
}
...
Run Code Online (Sandbox Code Playgroud)
这是非常冗长的.我知道我可以这样做:
val var1 = if (obj.isDefined) obj.get.var1 else "default1"
val var2 = if (obj.isDefined) obj.get.var2 else "default2"
Run Code Online (Sandbox Code Playgroud)
这似乎仍然很奇怪.我知道我可以使用一个大的匹配并返回一个值对象或元组.
但我喜欢的是类似的东西:
val var1 = obj ? _.var1 : "default1"
val var2 = obj ? _.var2 : "default2"
Run Code Online (Sandbox Code Playgroud)
这可能不知何故?
假设,我有两个选择:
val a: Option = Some("string")
val b: Option = None
Run Code Online (Sandbox Code Playgroud)
如何有效地检查是否定义了a和b?
我现在可以写下这样的东西:
if (a.isDefined && b.isDefined) {
....
}
Run Code Online (Sandbox Code Playgroud)
但是,它看起来很丑陋而且效率不高.
所以.怎么做?什么是最佳做法?
UPDATE
我想做我的业务逻辑.
if (a.isDefined && b.isDefined) {
....
SomeService.changeStatus(someObject, someStatus)
...
/* some logic with a */
/* some logic with b */
}
Run Code Online (Sandbox Code Playgroud) 我有一张地图,想要:
我有几种方法可以做到这一点
val map: Map[String, Int] // defined as such for simplification
// 1 short but confusing with error handling
def getValue(key: String): Int = {
map.getOrElse(key, scala.sys.error(s"No key '$key' found"))
}
// in case you don't know scala.sys.error
package object sys {
def error(message: String): Nothing = throw new RuntimeException(message)
}
Run Code Online (Sandbox Code Playgroud)
// 2 verbose
def getValue(key: String): Int = {
try {
map(key)
} catch {
case _: Throwable => scala.sys.error(s"No key '$key' found")
}
} …Run Code Online (Sandbox Code Playgroud) 据我所知,我们应该避免null在Scala中使用.如果某些字段在逻辑上不具有" Option无价值",那么我们不应该使用以避免过度使用Options.
所以让我们来看看代码.我有课
case class User (name: String)
Run Code Online (Sandbox Code Playgroud)
并且我100%确定该name字段不能null,因为它我只使用String而不是Option[String].
问题是一些标准的Scala方法回到了我的身边Option.(在我的例子中,该IterableLike#find方法返回Option)
所以问题是User当我有name包装时我如何创建实例Option?要清楚一点,这就是代码:
val userName: Option[String] = myList.find(...)
val user = User(userName.get) // or may be I should use userName.orNull ? or throw exception?
Run Code Online (Sandbox Code Playgroud)
我听说这Option.get不是优雅的解决方案.orNull方法几乎相同get.