我想从Iterable[Try[Int]]中提取所有有效值的列表(Iterable[Int])
val test = List(
Try(8),
Try(throw new RuntimeException("foo")),
Try(42),
Try(throw new RuntimeException("bar"))
)以下是从test打印所有有效值的方法
for {
n <- test
p <- n
} println(p)
// Output
// 8
// 42但是,当我尝试将有效值保存到列表时,我收到了一个错误:
val nums: Seq[Int] = for {
n <- list
p <- n // Type mismatch. Required: IterableOnce[Int], found Try[Int]
} yield(p)
println(nums)如何修复该错误以及引发该错误的原因?
发布于 2020-05-13 07:14:33
尝试收集
test.collect { case Success(value) => value }
// res0: List[Int] = List(8, 42)在for- corresponds格式中,与
for { Success(p) <- test } yield p两者都利用了Constructor Patterns,它在幕后执行isInstanceOf类型测试,然后是asInstanceOf类型转换。Verbosly,它对应于类似于
test
.filter (_.isInstanceOf[Success[Int]])
.map (_.asInstanceOf[Success[Int]].value)下面的for-comprehension不起作用,因为其中的monad必须对齐
for {
n <- test // List monad
p <- n // does not align with Try monad
} yield (p)上面的for-comprehension去糖化成
test.flatMap((n: Try[Int]) => n.map((p: Int) => p))看一下flatMap的签名,我们看到它需要一个函数
Try[Int] => IterableOnce[Int]同时我们还提供
Try[Int] => Try[Int]因为n.map((p: Int) => p)返回Try[Int]。现在,下面的for- different是一个完全不同的问题
for {
n <- test
p <- n
} println(p)由于缺少yield,因此它可以简化为
test.foreach((n: Try[Int]) => n.foreach((p: Int) => println(p)))其中foreach需要以下类型的函数
Try[Int] => Unit我们确实提供了它,因为n.foreach((p: Int) => println(p))确实返回了Unit。
发布于 2020-05-13 10:30:01
您还可以尝试:
val nums: Seq[Int] = list.map(_.toOption).flatten或
val nums: Seq[Int] = list.flatMap(_.toOption)https://stackoverflow.com/questions/61763561
复制相似问题