首页 文章

在Scala中不能失败的未来

提问于
浏览
5

是否有一个 Future 的概念在Scala中无法失败?

我正在转换 Future[Result] ,这可能会失败 - 因此我处理 FailureSuccess -into Future[Option[String]] ,带有从失败或成功状态派生的可选错误消息 . 到现在为止还挺好 .

现在,我想正式(即,在类型系统的帮助下)记住,这个未来将永远保持 Success ,并且我将来不需要处理失败案例 .

有一种聪明的方法吗?

2 回答

  • 3

    这不是类型标记的用途吗?

    scala> type Tagged[U] = { type Tag = U }
    defined type alias Tagged
    
    scala> type @@[T, U] = T with Tagged[U]
    defined type alias $at$at
    
    scala> trait OK ; trait Uncertain
    defined trait OK
    defined trait Uncertain
    
    scala> type Sure[A] = Future[A] @@ OK
    defined type alias Sure
    
    scala> type Unsure[A] = Future[A] @@ Uncertain
    defined type alias Unsure
    
    scala> val f = Future.successful(42).asInstanceOf[Sure[Int]]
    f: Sure[Int] = Future(Success(42))
    

    然后

    scala> object X { def p(f: Sure[_]) = "sure" ; def p(f: Unsure[_])(implicit d: DummyImplicit) = "unsure" }
    defined object X
    
    scala> X.p(f)
    res1: String = sure
    

    当然,它在 Map 下并不确定 .

  • 6

    你不能这样做"with the help of type system"因为类型系统无法保证 Future 不会失败,即使你保证不会失败 .

    考虑一下:

    Future { doStuff(); }
       .recover { case _ => "Failed!" } // Now it always succeeds
       .map { _ => Seq.empty[String].head }  // Now it does not.
    

    即使你要进行任何进一步的转换,一旦声明 Future 总是成功,那仍然无济于事,因为异常处理程序(或者你将原始未来转换为"always succeeding one"所做的任何事情)都可能抛出 .

    Update: 如下面的评论中所指出,上面的代码片段不正确: .map 的结果与 .recover 的结果不同 Future . 然而,重点是 . 这是正确的插图:

    Future { doStuff }
      .recover { case _ => Seq.empty[String].head }
    

相关问题