scala映射的正确使用

scala映射的正确使用,scala,functional-programming,Scala,Functional Programming,我发现自己在选项值上使用Scala映射函数,如下所示: optionVal.map( val => { doSomethingWith(val) doSomethingElseWith(val) // etc. (an example could be executing a database query) }) optX match { case Some(x) => doSomething(x) case None => doSomethingE

我发现自己在选项值上使用Scala映射函数,如下所示:

optionVal.map( val => {
  doSomethingWith(val)
  doSomethingElseWith(val)
  // etc. (an example could be executing a database query)
})
optX match {
  case Some(x) => doSomething(x)
  case None    => doSomethingElse()
}
其中optionVal可以是,例如:

Option[String]
换句话说,我使用它作为一种方法来确保选项中填充了一些内容,如果是这样,则执行一个语句块

对于来自Java世界的我来说,这似乎有点奇怪和复杂,在Java世界中,我只需对对象执行if检查(
if(someObject!=null){//executestatements}
)。而且,从语义上看,它可能不是map函数想要做的事情,即使它可以工作。因此,我想检查这是否是在Scala中执行此操作的正确/惯用方法。

如果
doSomethingwith(value)
返回
Unit
,则可以使用
foreach

def doSomethingWith(value: Int): Unit = println(value)

val opt: Option[Int] = Some(1)

opt.foreach{ value =>
    doSomethingWith(value)  // prints the value
}

val noOpt: Option[Int] = None 

noOpt.foreach{ value =>
    doSomethingWith(value)   // Does nothing, because noOpt is empty.
}
如果要映射(以某种方式返回)
选项中的值
,请继续使用
映射

选项
映射到
单元
是无害的,但是使用
foreach

会使您的代码更具可读性,如果
doSomethingwith(value)
返回
单元
,则可以使用
foreach

def doSomethingWith(value: Int): Unit = println(value)

val opt: Option[Int] = Some(1)

opt.foreach{ value =>
    doSomethingWith(value)  // prints the value
}

val noOpt: Option[Int] = None 

noOpt.foreach{ value =>
    doSomethingWith(value)   // Does nothing, because noOpt is empty.
}
如果要映射(以某种方式返回)
选项中的值
,请继续使用
映射


选项
映射到
单元
是无害的,但是使用
foreach

@LimbSoup的答案绝对适合于只调用没有返回类型的副作用函数的情况。为了完整性起见,这里有一些在Scala中使用选项值的其他方法。在使用返回值的函数时,您已经使用
map
函数正确识别了一种更惯用的方法:

val optX : Option[Int] = Some(1)
optX map { _ + 1 }    // returns Some[Int](2)

val optY : Option[Int] = None
optY map { _ + 1 }    // returns None
此行为扩展到其他功能,如
过滤器
折叠
。作为语法糖,您还可以使用
进行理解,就像在列表中一样

for (x <- optX) yield (x + 1)  // desugars to 'optX.map(_ + 1)'
for (x <- optX) doSomething(x) // desugars to 'optX.foreach(x => doSomething(x))'
这适用于需要if/else类型的行为,而不是基于是否有值来执行或不执行函数

使用一系列选项时,可以使用
flatMap
去除
None

// Applies a map to only the types with values
Seq(Some(1), Some(2), Some(3), None, None, None, Some(4)) flatMap { _ + 1 }  // returns Seq(2, 3, 4, 5)

最后,您可以完全抛开谨慎,然后调用
。获取您的选项类型。你可能不应该,但你可以使用它。如果是“Some”,则返回未包装的值,如果是“None”,则抛出异常。

@LimbSoup的答案绝对适用于只调用没有返回类型的副作用函数的情况。为了完整性起见,这里有一些在Scala中使用选项值的其他方法。在使用返回值的函数时,您已经使用
map
函数正确识别了一种更惯用的方法:

val optX : Option[Int] = Some(1)
optX map { _ + 1 }    // returns Some[Int](2)

val optY : Option[Int] = None
optY map { _ + 1 }    // returns None
此行为扩展到其他功能,如
过滤器
折叠
。作为语法糖,您还可以使用
进行理解,就像在列表中一样

for (x <- optX) yield (x + 1)  // desugars to 'optX.map(_ + 1)'
for (x <- optX) doSomething(x) // desugars to 'optX.foreach(x => doSomething(x))'
这适用于需要if/else类型的行为,而不是基于是否有值来执行或不执行函数

使用一系列选项时,可以使用
flatMap
去除
None

// Applies a map to only the types with values
Seq(Some(1), Some(2), Some(3), None, None, None, Some(4)) flatMap { _ + 1 }  // returns Seq(2, 3, 4, 5)
最后,您可以完全抛开谨慎,然后调用
。获取您的选项类型。你可能不应该,但你可以使用它。如果是“Some”,则返回未包装的值;如果是“None”,则抛出异常。

for(value)或
for(value)