关于 cats-effect-io
面向 Scala 开发者的 Cats Effect 技能,指导如何显式建模副作用并组织并发。内容涵盖效果类型、阻塞调用、资源初始化和效果执行边界。
主要功能
- 01将副作用建模为效果值
- 02延迟时间、随机数与可变对象分配
- 03选择最小 Cats Effect 能力
- 04按取消需求处理阻塞调用
- 05采用结构化并发与 Dispatcher
适用场景
- 01设计效果化 Scala API
- 02封装 Java 阻塞操作
- 03初始化共享可变服务
- 04衔接基于回调的 API
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ alexandru/ skills --skill cats-effect-io安装后在 Claude Code 中输入/cats-effect-io确认已加载。
附带文件references/cats-effect-io.mdscripts/verify-examples.scala
详细介绍
Cats Effect IO(Scala)
快速开始
- 将每个副作用和非确定性来源都视为一个效果值:返回
IO[A]、SyncIO[A]或F[A],并使用满足需求的最小 Cats Effect 能力。 - 挂起每次产生副作用的调用,而不是预先计算结果。
Instant.now()、随机数/UUID 生成、环境读取,以及new Array[...]之类的可变对象分配,都应放在IO(...)、Sync[F].delay、Clock、Random或有效果的工厂方法中。 - 通过
IO/F/Resource工厂初始化共享可变状态,并传递生成的引用或服务。不要在构造函数、顶层 val 或默认参数中隐藏副作用。 - 默认使用
IO.interruptible(或Sync[F].interruptible)包装 Java 阻塞式使用阶段调用;获取资源、运行终结器以及不能中断的操作则使用blocking。 - 使用
Resource获取和释放资源,并使用IOApp作为程序入口。 - 优先使用结构化并发(
parTraverse、parMapN、background、Supervisor),而非手动管理 fiber。 - 不要在应用代码或测试中使用
unsafeRun*(unsafeRunSync、unsafeRunAndForget等);与非 Cats Effect 回调 API 进行互操作时,请使用Dispatcher。 - 有关概念、配方、常见问题指南和经过验证的示例,请阅读
references/cats-effect-io.md。 - 深入了解
Resource,请使用cats-effect-resource技能(安装:npx skills add https://github.com/alexandru/skills --skill cats-effect-resource)。
工作流
- 找出每个副作用和非确定性值,包括时间、随机值、可变对象分配,以及共享状态的读写。
- 选择效果类型:具体的
IO,或使用最小能力(Clock、Random、Sync、Async、Temporal、Concurrent等)的多态F[_]。 - 使用
IO(...)、IO.interruptible、IO.blocking、IO.async或对应的类型类操作包装有副作用的代码。 - 将有状态服务的初始化移入返回
F[A]或Resource[F, A]的create/resource工厂方法。 - 使用
flatMap/for-comprehensions 和集合组合器(traverse、parTraverse)组合效果。 - 使用并发原语(
Ref、Deferred、Queue、Semaphore、Supervisor)和结构化并发,避免 fiber 泄漏。 - 将效果的执行保留在边界处(
IOApp、框架运行时);对于回调式互操作,请通过Dispatcher桥接。
副作用规则(适用于 IO、SyncIO 和 F[_]: Sync/Async)
- 所有有副作用的函数都必须返回包装在
IO中的结果(或使用 Cats Effect 类型类/能力的F[_])。 - 副作用包括所有非确定性(调用点并非引用透明):
- 任何 I/O(文件、套接字、控制台、数据库)。
Instant.now()、System.currentTimeMillis()、Random.nextInt()、UUID.randomUUID()。- 读取环境变量、系统属性、时钟、随机源或共享可变状态。
- 分配或返回可变结构,且其标识或变更可能逸出(
Array、mutable.Map、Java 集合、AtomicReference、缓存)。
- 仅当整个可变代码块都被挂起且没有可变值逸出时,才允许私有局部变更。
阻塞 I/O 规则
- 对阻塞式使用阶段操作,优先使用
IO.interruptible/Sync[F].interruptible。这会让取消有机会中断底层线程,是网络/套接字类阻塞 API 的正确默认做法。 - 不要因为尚未证明每个 Java API 都会遵循中断,就不使用
interruptible;有些 API 仍会忽略中断,因此当取消响应能力很重要且测试表明仅靠中断不足时,请添加特定于资源的取消协议。 - 对获取、清理和释放操作(
Closeable#close、AutoCloseable#close)使用IO.blocking/Sync[F].blocking;尝试中断这些操作可能导致生命周期状态不明确。
输出要求
- 在签名中明确标示副作用(
IO/SyncIO或F[_]: Sync/Async);此处的指导同样适用于具体的IO和多态的F[_]。 - 使用能够支持所需操作的最小类型类约束。
- 将副作用保留为值;不要在构造函数或顶层
val中执行副作用。 - 添加或修改 Scala 示例时,更新并编译随附的
scripts/verify-examples.scala脚本。
执行和测试规则
- 禁止在生产代码和测试代码中使用
unsafeRun*,包括import cats.effect.unsafe.implicits.global。 - 如果互操作需要从非 Cats-Effect 回调中运行副作用,请使用
Dispatcher。 - 优先采用原生的副作用测试风格(返回
IO[Assertion]/F[Assertion]),而不是手动运行副作用。 - 单元测试中避免使用
IO.sleep/Thread.sleep,除非使用TestControl虚拟时间。
参考资料
- 加载
references/cats-effect-io.md,了解文档摘要和模式。 - 查看
references/cats-effect-io.md中的具体示例;代表性检查脚本是scripts/verify-examples.scala。 - 对于
Resource专属的工作流和模式,请使用cats-effect-resource技能(安装命令:npx skills add https://github.com/alexandru/skills --skill cats-effect-resource)。
评论
支持 Markdown