如何使用时间表向控制台重复消息

问题描述

我正在尝试了解时间表的工作原理,我只想使用时间表向控制台显示一条简单的消息。

import zio.console._
import zio._
import scala.util.Try
import zio.duration._
import zio.clock._

object MyApp extends zio.App {

  def run(args: List[String]) =
    myAppLogic.exitCode

  val myAppLogic =
    for {
      sequential = Schedule.recurs(10) andThen Schedule.spaced(1.second)
      _ <-  ZIO.effectTotal{ "hello" }.retry(sequential)
    } yield ()

}

我收到此错误

错误处理操作假定您的效果可能会失败。然而, 您的效果对于错误类型没有任何意义,这意味着它不能 失败,所以没有必要处理失败。找出哪个 您可以使用的方法代替此操作,请参阅参考 图表位于:https://zio.dev/docs/can_fail [错误] _

我正在返回一个具有可抛出错误类型的 Task[String]。如果我用 effect 替换 effectTotal ,那么我不会收到编译错误,但程序只是存在,甚至一次都没有重复 hello 这个词。

在这里遗漏了什么概念?

解决方法

首先,for-comprehension 的第一行不能有 =。您需要将您的纯值包含在 ZIO.succeed 中或将其置于 for-comprehension 之外。

"Hello" 是一个纯字符串。您可以使用 ZIO.effectTotal,但从技术上讲它不会产生任何副作用,因此您也应该在此处使用 succeed

retry 在失败时重试,但 effectTotal / succeed 不会失败。您应该改用 repeat

import zio._
import zio.duration._

object MyApp extends zio.App {
  def run(args: List[String]) =
    myAppLogic.exitCode

  val myAppLogic =
    for {
      sequential <- ZIO.succeed(Schedule.recurs(10) andThen Schedule.spaced(1.second))
      _ <-  ZIO.succeed("hello").repeat(sequential)
    } yield ()
}

现在修复了错误,它仍然不会显示您的文本,因为您只是在生成值(不是副作用)而不打印它们(副作用)。

正确的代码应该是这样的:

import zio._
import zio.duration._
import zio.console._

object MyApp extends zio.App {
  def run(args: List[String]) =
    myAppLogic.exitCode

  //leave this out of the for-comprehension
  val sequential = Schedule.recurs(10) andThen Schedule.spaced(1.second)

  val myAppLogic = putStrLn("hello").repeat(sequential)

//  Or you could suspend the `println` side effect with `effectTotal` (doesn't fail but produces side effects)
//  val myAppLogicAlt = ZIO.effectTotal(println("hello")).repeat(sequential)
}