Managed

Managed 是一个封装了资源的 acquire 和 release 的数据结构。

Managed[E, A] 表示一个类型为 A 的托管资源,它可以通过 use 方法被使用。资源将在使用之前自动获取资源,并在使用之后自动释放资源。

如果资源无法在 use 范围内生效,这意味着您可能在获得资源后,在 use 中将其浪费掉,然后在资源消耗完后再次使用它,根据资源提供的功能类型它可能已经不再有效,并且可能会因检查错误而失败。

import zio._
def doSomething(queue: Queue[Int]): UIO[Unit] = IO.unit

val managedResource = Managed.make(Queue.unbounded[Int])(_.shutdown)
val usedResource: UIO[Unit] = managedResource.use { queue => doSomething(queue) }

在此示例中,Managed 类在调用 use 时创建队列,并在 doSomething 完成时调用 shutdown

创建一个 Managed

如上例所示,可以通过传递 acquire 函数和 release 函数来创建 Managed

也可以从 effect 中创建。在这种情况下,release 函数将不执行任何操作。

import zio._
def acquire: IO[Throwable, Int] = IO.effect(???)

val managedFromEffect: Managed[Throwable, Int] = Managed.fromEffect(acquire)

您也可以从纯值创建 Managed

import zio._
val managedFromValue: Managed[Nothing, Int] = Managed.succeed(3)

ZIO 环境中的 Managed

Managed[E, A] 实际上是 ZManaged[Any, E, A] 的别名。如果您希望acquire,release 或 use 函数中使用环境 R,请使用 ZManaged 来代替 Managed

import zio._
import zio.console._

val zManagedResource: ZManaged[Console, Nothing, Unit] = ZManaged.make(console.putStrLn("acquiring"))(_ => console.putStrLn("releasing"))
val zUsedResource: URIO[Console, Unit] = zManagedResource.use { _ => console.putStrLn("running") }

合并 Managed

可以使用 flatMap 将多个 Managed 合并在一起,以得到获取和释放所有资源的单个 Managed。

import zio._
val managedQueue: Managed[Nothing, Queue[Int]] = Managed.make(Queue.unbounded[Int])(_.shutdown)
val managedFile: Managed[IOException, File] = Managed.make(openFile("data.json"))(closeFile)

val combined: Managed[IOException, (Queue[Int], File)] = for {
    queue <- managedQueue
    file  <- managedFile
} yield (queue, file)

val usedCombinedRes: IO[IOException, Unit] = combined.use { case (queue, file) => doSomething(queue, file) }

Leave a Reply
Your email address will not be published.
*
*

BACK TO TOP