【问题标题】:Is it possible to do finally with Try? [duplicate]是否有可能最终与 Try 一起做? [复制]
【发布时间】:2017-11-11 15:39:08
【问题描述】:

我是Scala的新手,看了Try::apply的源代码

def apply[T](r: => T): Try[T] =
  try Success(r) catch {
    case NonFatal(e) => Failure(e)
  }

它只是捕获非致命异常。但是如果我需要 finally 子句怎么办?是否可以用Try 以功能方式模拟它?我的意思是像

try{
   //acquire lock
   //do some
} finally {
  // release lock
}

Try{
   //acquire lock
   //do some
} 
//Now how to release?

【问题讨论】:

    标签: scala exception


    【解决方案1】:

    here 已经回答了类似的问题。

    TLTR; Try monad 没有标准的方法来做到这一点。

    通常的解决方法是这样的:

    def use[A <: { def close(): Unit }, B](resource: A)(code: A ⇒ B): B =
        try {
            code(resource)
        } finally {
            resource.close()
        }
    

    你可以像这样使用:

    val path = Paths get "/etc/myfile"
    use(Files.newInputStream(path)) { inputStream ⇒
        val firstByte = inputStream.read()
        ....
    }
    

    here 解释的另一种方法意味着您通过添加附加方法“withRelease”来“扩展”标准“Try”

    implicit class TryOps[A <: { def close(): Unit }](res: Try[A]) {
      def withRelease() = res match {
        case Success(s) => res.close(); res
        case Failure(f) => res.close(); res
      }
    }
    

    那么,

    Try {
       val inputStream = Files.newInputStream(path))
       ...
       inputStream
    }.withRelease()
    

    【讨论】:

      【解决方案2】:

      由于Try 解析为一个值并且它不会在出现故障时展开堆栈,因此您可以在Try 执行后简单地执行清理操作。例如:

      val someLock = ??? // acquire some lock
      val result = Try {
        // do something and return a result
      }
      someLock.release()
      

      如果您愿意,可以滚动您自己的助手,将所有内容都保存在一个表达式中:

      def withLock[A](f: Lock => A): Try[A] = {
        val lock = ??? // acquire the lock
        val res = f(lock)
        lock.release()
      }
      

      然后你可以写:

      val res = withLock { lock =>
       // some operation
      }
      

      这通常被称为贷款模式

      【讨论】:

      • 为什么是f: Lock =&gt; A?如果您从外部获取锁,为什么要将锁传递给函数?看起来像一个名字thunk会做吗? f: =&gt; A
      • 在锁定的情况下,是的,可能。该模式更适合需要在block 内使用的连接。
      猜你喜欢
      • 2011-01-25
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      • 2011-05-02
      • 2016-01-06
      • 1970-01-01
      • 2021-09-23
      • 2020-01-18
      相关资源
      最近更新 更多