Scala 将元组向量映射到对象向量

Scala map a Vector of tuples to vector of object

import scala.concurrent.duration._
import scala.language.implicitConversions
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global

object test extends App {  
  case class Person(name: String, age: Int)

  implicit def t2p(t: (String, Int)) : Person = Person(t._1, t._2)

  val f:Future[Vector[(String, Int)]] = Future {
    Vector(("One", 1), ("Two", 2))
  }

  val s = f.mapTo[Vector[Person]]

  Await.result(s.map { _ foreach { x => println(x)}}, 5.seconds)
}

我正在尝试将元组的 Vector 转换为 Vector[Person],但上面的代码导致转换异常,即使存在隐式元组到 Person 的转换函数?

线程 "main" java.lang.ClassCastException 中出现异常:scala.Tuple2 无法转换为 example.test$Person 在 example.test$$anonfun$2$$anonfun$申请$1.apply(test.scala:19) 在 scala.collection.Iterator$class.foreach(Iterator.scala:727) 在 scala.collection.AbstractIterator.foreach(Iterator.scala:1157) 在 scala.collection.IterableLike$class.foreach(IterableLike.scala:72) 在 scala.collection.AbstractIterable.foreach(Iterable.scala:54) 在 example.test$$anonfun$2.apply(test.scala:19) 在 example.test$$anonfun$2.apply(test.scala:19)

谢谢。

直接使用:

  val f:Future[Vector[Person]] = Future {
    Vector(("One", 1), ("Two", 2))
  }

您可以查看此答案以获取有关将 mapToFuture 一起使用的更多信息:Using mapTo with futures in Akka/Scala

mapTo 只是尝试转换,因此尝试将 Vector[(String, Int)] 转换为 Vector[Person] 当然会失败。

您需要一个将 (String, Int) 转换为 Person 的函数,该函数是 Person.apply.

的元组版本

因此,替换

f.mapTo[Vector[Person]]

f.map(_.map(Person.tupled))

这是mapTo的签名:

def mapTo[S](implicit tag: ClassTag[S]): Future[S]

它不带任意转换函数。删除你的 t2p 代码仍然会以同样的方式编译和失败。 mapTo 实际上执行了 Java 风格的转换,这就是为什么它需要 ClassTag.

相反,您可以这样做:

val s = f.map(vec => vec.map(Person.tupled))