Scala for Backend Engineering & Functional Programming · 课时

IO 单子

纯效果

第 2 / 4 课13 个步骤

IO 单子 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Scala for Backend Engineering & Functional Programming 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

什么是 IO?

Cats Effect 中的 IO[A] 是对某个计算的描述。运行该计算时,它可能执行副作用并产生 A 类型的值。它本身是一个纯值——在运行它之前不会发生任何事情。

延迟执行副作用

使用 IO(...) 或 IO.delay(...) 包装副作用。创建 IO 时不会执行其中的主体,只有运行它时才会执行。

import cats.effect.IO

val program: IO[Unit] = IO(println("Hello, IO!"))
// Nothing printed yet — program is just a description

引用透明性

由于 IO 是惰性的,您可以用一个 IO 值替换其定义,而不改变程序行为。这种引用透明性让带有效应的代码更容易推理和重构。

纯值

使用 IO.pure 提升一个已经计算完成的值。不要将副作用放入 pure 中,因为它会立即求值。对于副作用,请使用 IO.delay 或 IO(...)。

import cats.effect.IO

val p: IO[Int] = IO.pure(42)
// 42 is computed already; pure just wraps it

map 与 as

map 会转换 IO 的结果。as 会用一个常量替换结果。二者都不会运行效应,而是构建一份更大的描述。

import cats.effect.IO

val len: IO[Int] = IO("hello").map(_.length)
val done: IO[String] = IO(println("ran")).as("done")

使用 IOApp 运行

要执行一个 IO 程序,请扩展 IOApp 并实现 run,返回一个 IO[ExitCode]。运行时会在基于纤程的调度器上对其求值。

import cats.effect.{IO, IOApp, ExitCode}

object Main extends IOApp {
  def run(args: List[String]): IO[ExitCode] =
    IO(println("Running!")).as(ExitCode.Success)
}

IOApp.Simple

对于不需要参数或自定义退出码的程序,请扩展 IOApp.Simple,并提供一个 run: IO[Unit]。

import cats.effect.{IO, IOApp}

object Hello extends IOApp.Simple {
  def run: IO[Unit] = IO.println("Hello, world!")
}

IO.println

Cats Effect 提供了 IO.println,用于方便地执行带有效应的打印操作。它返回 IO[Unit],并且只有在运行时才会打印。

import cats.effect.IO

val greet: IO[Unit] = IO.println("effectful output")

捕获异常

如果被包装的效应抛出异常,失败会被捕获在 IO 内部,而不是逸出。此时,IO 会变成一个失败值,您可以稍后处理它。

import cats.effect.IO

val boom: IO[Int] = IO(throw new RuntimeException("fail"))
// Creating boom does NOT throw; running it would

普通 Scala 的比较

如果没有效应类型,副作用会立即执行,并且难以组合。IO 会延迟执行副作用,因此一个自包含的 Scala 程序会立即打印,而使用 IO 时则会延迟打印。

object Main {
  def main(args: Array[String]): Unit = {
    val eager = println("runs now") // executed immediately
    println("second line")
  }
}

为什么使用 IO?

IO 为您提供:

  • 纯粹性 — 将效应表示为值
  • 可组合性 — 用小片段构建程序
  • 安全性 — 跟踪错误和资源
  • 并发性 — 使用轻量级纤程

快速检查

IO(println("hi")) 中的副作用实际上会在什么时候执行?

回顾

IO monad 将效应表示为纯的、惰性的值:

  • IO(...) / IO.delay 延迟执行效应
  • IO.pure 包装已经计算完成的值
  • IOApp / IOApp.Simple 运行程序
  • 异常会被捕获,而不是立即抛出

接下来:组合多个 IO 操作。

免费开始

用 AI 导师学习 Scala — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
39
课程
143

常见问题解答

「IO 单子」课时是免费的吗?

是的 — 「IO 单子」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

「IO 单子」这节课中我会学到什么?

纯效果 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「IO 单子」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Scala for Backend Engineering & Functional Programming 课中编写并运行代码吗?

能。每节 Scala for Backend Engineering & Functional Programming 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Cats 类型类
  2. IO 单子
  3. 组合 IO
  4. IO 中的错误处理
← 返回 Scala for Backend Engineering & Functional Programming