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
。
Contents
hide
创建一个 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) }