有人可以教我map
和flatMap
的财产使用案例吗?
在Option
案例中,我知道这两种方法都有每个签名,def map(A => B): Option[B]
和def flatMap(A => Option[B]): Option[B]
。
所以,我可以通过两种方式获得一些价值:
scala> val a = Some(1).map(_ + 2)
a: Option[Int] = Some(3)
scala> val a2 = Some(1).flatMap(n => Some(n + 2))
a2: Option[Int] = Some(3)
当我写一个方法:def plusTwo(n: Int)
时,
def plusTwo(n: Int): Int = n + 2
Some(1).map(plusTwo)
和
def plusTwo(n: Int): Option[Int] = Some(n + 2)
Some(1).flatMap(plusTwo)
flatMap
可以转换为for-comprehension,并且几乎所有方法都返回值Option
包裹好吗?
答案 0 :(得分:2)
假设您有一个列表:
let widthContr = NSLayoutConstraint(item: unitControl,
attribute: NSLayoutAttribute.width,
relatedBy: NSLayoutRelation.equal,
toItem: cell,
attribute: NSLayoutAttribute.notAnAttribute,
multiplier: 1,
constant: 0.5)
cell.addConstraints([widthContr])
现在让我们继续你的例子吧。假设我们有一个返回选项的函数:
val names = List("Benny", "Danna", "Tal")
names: List[String] = List(Benny, Danna, Tal)
map函数的工作原理是将函数应用于列表中的每个元素:
def f(name: String) = if (name contains "nn") Some(name) else None
另一方面,flatMap应用一个函数,该函数返回列表中每个元素的序列,并将结果展平为原始列表
names.map(name => f(name))
List[Option[String]] = List(Some(Benny), Some(Danna), None)
如您所见,flatMap删除了Some / None图层并仅保留原始列表。
答案 1 :(得分:0)
您的函数plusTwo
会返回所有输入的有效结果,因为您可以向任何Int添加2。
无需定义它返回Option [Int],因为永远不会返回None值。这就是你使用Option.map
这类功能的原因但并非所有函数都对每个输入都有有意义的结果。例如,如果你的函数按函数参数划分某个数字,那么将零传递给该函数是没有意义的。
假设我们有一个功能:
def divideTenBy(a: Int): Double
当你用零调用它时,抛出ArithmeticException。然后你必须记住捕获这个异常,这样才能使我们的函数更容易出错。
def divideTenBy(a: Int): Option[Double] = if (a == 0) None else Some(10 / a)
使用这些函数可以使用flatMap,因为在可选(左操作数)中可以有'None'值,或者给定的函数可以返回None。
现在您可以安全地将此函数映射到任何值:
scala> None.flatMap(divideTenBy)
res9: Option[Double] = None
scala> Some(2).flatMap(divideTenBy)
res10: Option[Double] = Some(5.0)
scala> Some(0).flatMap(divideTenBy)
res11: Option[Double] = None