scala:映射元组的未来

Zen*_*aro 3 scala

我有一个Future这样TupleFuture[(WriteResult, MyObject)] mytuplefuture,我想映射它并做一些事情,MyObject所以我这样做:

mytuplefuture.map((wr,obj)=>{ //do sth});
Run Code Online (Sandbox Code Playgroud)

但我的 eclipse scala IDE 不允许并建议我这样做:

mytuplefuture.map{ case(wr,obj) => { //do sth }}
Run Code Online (Sandbox Code Playgroud)

这两者有什么区别?

我习惯了做第一个,我不知道第二个,直到我尝试返回包裹在 future 中的元组

myfuture.map((obj) => { // do sth with obj })
Run Code Online (Sandbox Code Playgroud)

很明显,我正在映射 Future 的内容并用它做一些事情,这将返回另一个 future,因为原始的 myfuture 只包含未来的某些东西(obj)。

有人可以解释一下吗?

Mik*_*len 5

区别是这样的:

map是一个以函数作为参数的高阶函数( HOF )。该函数(为了方便起见,我们将其称为映射函数)本身接受一个参数,即已完成的值Future。在这种特殊情况下,该值恰好是一个元组。您的第一次尝试假设元组可以分成两个参数,然后映射函数会接受这两个参数 - 但这不会发生,因此会出现错误。

您似乎可以像这样定义映射函数(请注意参数周围的额外括号):

mytuplefuture.map(((wr,obj)) => /* do sth */)
Run Code Online (Sandbox Code Playgroud)

然而, Scala编译器目前不支持此功能。(也就是说,我认为这可能是未来Scala版本的一个功能。)

因此,另一种方法是使用该语句将映射函数编写为部分函数case。下列:

mytuplefuture.map {
  case (wr,obj) => //
}
Run Code Online (Sandbox Code Playgroud)

实际上是以下内容的一种简写:

mytuplefuture.map {
  tuple: (WriteResult, MyObject) => tuple match {
    case (wr,obj) => // do sth
  }
}
Run Code Online (Sandbox Code Playgroud)

事实上,这种简写通常对于除了破坏开放元组之外的情况很有用。例如:

myList.filter {
  case A => true
  case _ => false
}
Run Code Online (Sandbox Code Playgroud)

是缩写:

myList.filter {
  x => x match {
    case A => true
    case _ => false
  }
}
Run Code Online (Sandbox Code Playgroud)

因此,假设您只想查看MyObject元组的成员。您可以将其定义如下:

val myfuture = mytuplefuture.map {
  case (_, obj) => obj
}
Run Code Online (Sandbox Code Playgroud)

或者,使用元组参数明确:

val myfuture = mytuplefuture.map(tuple => tuple._2)
Run Code Online (Sandbox Code Playgroud)

这又可以简化为:

val myfuture = mytuplefuture.map(_._2)
Run Code Online (Sandbox Code Playgroud)

其中第一个下划线是映射函数第一个参数的简写。(第二个下划线,如 中所示_2,是元组中第二个值的名称的一部分,而不是简写 - 这是Scala可能会有点混乱的地方。)

前面三个示例都返回一个Future[MyObject].

如果您随后应用map该值,则本例中的单个映射函数参数将是您的MyObject实例。因此你现在可以写:

myfuture.map(obj => /* Do something with obj */)
Run Code Online (Sandbox Code Playgroud)

至于问题的其余部分,应用于 a值的映射函数Future确实适用于原始未来的结果,因为在第一个未来完成之前它无法执行。因此,map返回一个在第一个 future 完成时完成(成功或失败)的 future。

更新:澄清了实际的论点map是什么。感谢@AlexeyRomanov 纠正我的错误,感谢@RhysBradbury 指出我最初的错误。;-)

  • 两者都不正确。`map` 接受一个函数参数,这使得 `map` 本身成为一个高阶函数。这并不意味着它的参数是一个高阶函数(尽管它可以是)。 (2认同)