scala:映射元组的未来

时间:2017-10-19 11:43:51

标签: scala

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

mytuplefuture.map((wr,obj)=>{ //do sth});

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

mytuplefuture.map{ case(wr,obj) => { //do sth }}

这两者之间有什么区别?

我习惯做第一个,我不知道第二个,直到我尝试返回包含在未来的元组

myfuture.map((obj) => { // do sth with obj })
很明显,我正在绘制未来的内容,并用它做一些事情,这会带来另一个未来,因为原来的myfuture在未来只包含一些东西(obj)。

有人会解释吗?

2 个答案:

答案 0 :(得分:3)

区别在于:

map高阶函数 HOF ),它以函数作为参数。这个函数 - 为了方便我们称之为映射函数 - 它本身只需要一个参数,即完成的Future的值。在这种特殊情况下,这个值恰好是一个元组。你的第一次尝试假设元组可以被打开成两个参数,然后被映射函数接受 - 但这不会发生,因此错误。

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

mytuplefuture.map(((wr,obj)) => /* do sth */)

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

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

mytuplefuture.map {
  case (wr,obj) => //
}

实际上是一种简写:

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

事实上,这种速记通常对除了打开元组之外的其他情况很有用。例如:

myList.filter {
  case A => true
  case _ => false
}

简称:

myList.filter {
  x => x match {
    case A => true
    case _ => false
  }
}

所以,让我们说你只想看看元组的MyObject成员。您可以按如下方式定义:

val myfuture = mytuplefuture.map {
  case (_, obj) => obj
}

或者,使用元组参数显式:

val myfuture = mytuplefuture.map(tuple => tuple._2)

又可以简化为:

val myfuture = mytuplefuture.map(_._2)

其中第一个下划线是映射函数的第一个参数的简写。 (第二个下划线,如在_2中,是元组中第二个值的名称的一部分,并不是简写 - 这是 Scala 可能会让人感到困惑的地方。)< / p>

前三个示例中的所有示例都返回Future[MyObject]

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

myfuture.map(obj => /* Do something with obj */)

至于问题的其余部分,应用于Future值的映射函数确实适用于原始未来的结果,因为它可以& #39;执行直到第一个未来完成。因此,map返回在第一个未来完成时(成功或以其他方式)完成的未来。

更新:明确了map的参数究竟是什么。感谢@AlexeyRomanov让我说得对,感谢@RhysBradbury指出我的初始错误。 ; - )

答案 1 :(得分:-1)

不同之处在于,case表示对象的分解(或提取)(调用unapply,您可以自己实现)。

在这种情况下,

myfuture.map(obj => obj._2 ) obj - 是您的元组,因此您可以通过._1._2

访问其元素

mytuplefuture.map{ case(wr,obj) => { //do sth }}这会将元组分解为元素。

您可以通过case class使用此方法来更好地感受到差异,该方法带有默认的unapply实施

case class MyClass(int: Int)
List(MyClass(1)) map { myclass => myclass.int } // accesing the elements
List(MyClass(1)) map { case MyClass(i) => i + 1 } // decomposition 

在你的情况下,我会写

mytuplefuture.map(_.2).map( // do somthing )

P.S。 您可以为许多其他类(例如Option)进行提取。 它还允许您编写类似

的内容
val (a, b) = tuple
val MyClass(x) = myclass