ZIO环境建设

问题描述 投票:3回答:2

我开始尝试ZIO,并试图运行以下高度复杂的程序:

import logger.{Logger, _}
import zio.console._
import zio.{system, _}

object MyApp extends App {

  override def run(args: List[String]): ZIO[ZEnv, Nothing, Int] = {

    app
      .provideSome[Logger](_ => Slf4jLogger.create) //1 
      .fold(_ => 1, _ => 0)
  }

  val app: ZIO[Console with system.System with Logger, SecurityException, Unit] =
    for {
      _         <- info("This message from the logger") //2
      maybeUser <- system.env("USER")
      _         <- maybeUser match {
                      case Some(userName) => putStrLn(s"Hello ${userName}!")
                      case None => putStrLn("I don't know your name")
                    }
    } yield ()
}

(Slf4jLogger为https://github.com/NeQuissimus/zio-slf4j

如果我注释//1//2行,一切正常。但是在以上形式中,我收到类型不匹配错误:

Error:(13, 45) type mismatch;
 found   : logger.Slf4jLogger
 required: zio.console.Console with zio.system.System with logger.Logger
      .provideSome[Logger](_ => Slf4jLogger.create)

我不理解以下内容:

  1. 该程序在环境中需要一个Console和一个System实例,但是当我没有登录时,我以前不必.provide它。为什么?为什么我突然需要它?

  2. 根据scaladoc,.provideSome 提供运行此效果所需的*一些*环境,剩下R0。对我来说,这意味着我不必提供完整的环境类型,我可以一个接一个地添加所需的模块-但似乎期望完整的ZEnv类型,就像.provide-那么有什么意义呢?

  3. 我无法通过new Logger with Console.Live with system.System.Live实例化匿名类,因为Slf4jLogger在伴随对象中具有工厂方法。如何将这种工厂方法与其他特征一起使用?

  4. 由于使用Java创建记录器实例是有效的,因此.provide甚至是正确的调用函数吗?

PS:我能够以某种丑陋的方式使它工作:

    app
      .provideSome[ZEnv](_ =>
        new Console with Logger with system.System {
          override val console = Console.Live.console
          override val system = System.Live.system
          override val logger = Slf4jLogger.create.logger
        }
      ) //1
      .fold(_ => 1, _ => 0)

这会编译并运行,但是覆盖特质内部成员中的混合对象似乎不正确...

并且它与.provide的工作方式完全相同:

    app
      .provide(
        new Console with Logger with system.System {
          override val console = Console.Live.console
          override val system = System.Live.system
          override val logger = Slf4jLogger.create.logger
        }
      ) //1
      .fold(_ => 1, _ => 0)

发生了什么事?

scala scalaz-zio
2个回答
1
投票

让我尝试解释。


0
投票

恐怕您必须返回一个实例,该实例实现了您想提供的所有特征。

© www.soinside.com 2019 - 2024. All rights reserved.