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

How to repeat a message to console using a schedule

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

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 ()

}

我收到这个错误:

This error handling operation assumes your effect can fail. However, your effect has Nothing for the error type, which means it cannot fail, so there is no need to handle the failure. To find out which method you can use instead of this operation, please see the reference chart at: https://zio.dev/docs/can_fail [error] _ <- ZIO.effectTotal{ "hello" }.retry(sequential)

我正在返回一个具有可抛出错误类型的任务[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)
}