ZLayer.scoped和ZLayer.fromZio之间有什么区别?

3
我对ZIO中的许多不同方法感到困惑,它们似乎是在做同样的事情(至少在我这个新手的眼里)。
特别是像这样的东西:
val layer: RLayer[ServiceA with ServiceB, ServiceC] = ZLayer.scoped {
  for {
     a <- ZIO.service[ServiceA]
     b <- ZIO.service[ServiceB]
  } yield new ServiceCImpl(a, b)
}

vs
val layer2: RLayer[ServiceA with ServiceB, ServiceC] = ZLayer.fromZIO {
  for {
     a <- ZIO.service[ServiceA]
     b <- ZIO.service[ServiceB]
  } yield new ServiceCImpl(a, b)
}

这两个片段是在做同样的事情吗?如果不是,有什么区别?如果是,为什么会有两个?在什么情况下会使用其中一个而不是另一个?
1个回答

3
在你的情况下,他们正在做同样的事情。实际上,还有第三种方式,使用ZLayer.fromFunction
ZLayer.fromFunction(ServiceCImpl _)
// or:
ZLayer.fromFunction((a: ServiceA, b: ServiceB) => new ServiceCImpl(a,b))

这是我个人觉得最简单的方式。

那么有什么区别呢?

  • ZLayer.scoped 用于创建需要一些作用域资源的服务(例如打开文件并在“停止”服务时自动关闭文件,或者数据库连接)
  • ZLayer.fromZIO 用于创建没有需要管理的资源,但仍然存在潜在错误并且创建服务表示为 ZIO 的情况
  • ZLayer.fromFunction 用于创建服务时既不满足上述条件,也不会失败且不需要管理任何资源的情况

另请参阅 ZLayer 参考文档


谢谢!是的,我知道fromFunction,我的理解是它是fromZIO的一个简单情况的"捷径"。但是关于作用域资源,你能详细解释一下它是如何工作的吗?"作用域"到底是什么意思?如果我使用ZLayer.scoped(ZIO.from(Source.fromFile("foo"))),它会在某个时刻自动关闭文件吗?具体是什么时候?它又是如何知道如何"关闭"我的资源的呢? - undefined
1
说实话,我对"scope"和其中的"magic"还有点困惑。我觉得你写的代码可能不能自动处理,可能需要使用acquireRelease相关的内容。但是我不能确定,无法给出更确切的答案。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接