
for 推导式完全指南programming-scala-book-code-examples 中 20 个实用示例一次学会【免费下载链接】programming-scala-book-code-examplesThe code examples used in Programming Scala, 2nd and 3rd Editions (OReilly)项目地址: https://gitcode.com/gh_mirrors/pr/programming-scala-book-code-examples如果你刚接触 Scala一定对for推导式for comprehension又爱又恨它长得像循环实际却比循环强大得多。作为《Programming Scala第 2/3 版》官方配套代码仓库programming-scala-book-code-examples里藏着 20 多个可以直接运行的for推导式示例覆盖map、flatMap、守卫、模式过滤、Option/Either/Try链式处理等全部核心场景。本文带你逐个拆解这些实用示例从入门语法到真实项目写法一次学会 Scala for 推导式。为什么一定要学 for 推导式简单说for 推导式是把map、flatMap、withFilter、foreach组合起来的一层语法糖。它让链式调用变得像顺序代码一样可读还能优雅处理Option、Either、Try这些容器类型——不用写一堆match和return。// 一个 for 推导式 val upper1 for s - states yield s.toUpperCase // 等价于 val upper3 states.map(_.toUpperCase) 关键心法yield表示产出新集合没有yield的do写法则用于执行副作用相当于foreach。20 个实用示例总览从入门到实战 下面是src/script/scala/progscala3/forcomps/目录下全部核心示例按难度分为四组分组示例文件学习要点入门基础ForMap.scala最简for...yield转换入门基础ForFlatmap.scala嵌套遍历与flatMap展开入门基础ForGuard.scalaif守卫过滤元素入门基础ForForeach.scala无yield的副作用写法入门基础ForVariable.scala推导式内定义中间变量中级进阶ForTranslated.scala一步步还原成map/flatMap/foreach中级进阶ForOptionsSeq.scalaOption链式调用遇None即停中级进阶ForOptionsFilter.scala用模式匹配过滤Option序列中级进阶ForTries.scalaTry链式调用与异常短路中级进阶ForTriesSeq.scala过滤Try序列中的失败项中级进阶ForEithers.scalaEither链式调用与错误短路中级进阶ForEithersCombinators.scalaRight/Left上的组合器用法中级进阶ForEithersSeq.scala处理Either序列反模式警示ForOptionsBad.scala用return处理 Option 的坏味道反模式警示ForOptionsBad2.scala用foldLeft硬算的冗余写法编程思想RefTransparency.scala引用透明与错误返回的对比实战应用LoginFormValidatorSingle.scala登录表单校验实战实战应用LoginFormValidation.scala多字段校验的完整设计实战应用LoginFormValidatorNec.scala累积全部错误的Nec版本实战应用RemoveBlanks.scala文本清洗实用函数每个文件都有//注释标明其路径直接在命令行运行即可看到输出边跑边学效果最好。入门基础5 个示例看懂核心语法 ✅示例 1最简转换ForMap.scala把集合中每个元素做一次变换这是for推导式最基础的用法val states Vector(Alabama, Alaska, Virginia, Wyoming) val upper1 for s - states yield s.toUpperCase-读作从……中取出yield后跟转换表达式。你可以把它理解为给每个元素起个名字再加工比.map(_.toUpperCase)更易读。示例 2嵌套遍历ForFlatmap.scala一个推导式里可以写多个-实现每个元素再展开一层val results1 for s - states c - s // 对每个州名再遍历它的每个字符 yield s$c-${c.toUpper}它等价于states.flatMap(s s.toSeq).map(c ...)。记住口诀多个-等价于嵌套flatMap最后一个yield等价于map。示例 3if 守卫过滤ForGuard.scala在推导式中加入if条件只处理符合条件的元素val results1 for s - states c - s if c.isLower // 只取小写字符 yield s$c-${c.toUpper}这里的if在 Scala 中翻译成withFilter而不是filter目的是延迟求值、避免复制中间集合性能更好。示例 4副作用写法ForForeach.scala不需要yield产出新集合时用do关键字执行副作用等价于foreachvar lower1 Vector.empty[String] for s - states do lower1 lower1 : s.toLowerCase示例 5中间变量ForVariable.scala推导式内部可以用c2 ...定义中间变量让后续步骤复用逻辑更清晰val results1 for s - states c - s if c.isLower c2 s$c-${c.toUpper} yield (c, c2)中级进阶Option / Either / Try 三件套 for推导式真正的杀手锏是无缝串联多个可能失败的计算。无论Option、Either还是Try只要任意一步失败整条链立即短路返回无需手写match。示例 6Option 链ForOptionsSeq.scalaval resultFail for i1 - positiveOption(5) i2 - positiveOption(-1 * i1) // 这里返回 None链直接终止 i3 - positiveOption(25 * i2) i4 - positiveOption(-2 * i3) yield (i1 i2 i3 i4)示例 7Try 链ForTries.scala换成Try后任何一步抛异常都会得到一个Failure整条链立即停止——异常处理也能写成线性代码。示例 8Either 链ForEithers.scalaEither可以携带错误信息Left业务上最常用val result2 for i1 - positiveEither(5) i2 - positiveEither(-1 * i1) // 返回 Left链终止 i3 - positiveEither(25 * i2) i4 - positiveEither(-2 * i3) yield (i1 i2 i3 i4)示例 9模式过滤ForOptionsFilter.scala对Seq[Option[Int]]这样的容器可以直接用case Some(i) - options只保留成功的元素val results1 for case Some(i) - options yield (2 * i)ForTriesSeq.scala、ForEithersSeq.scala分别是Try与Either序列的同款玩法三个示例对照着看一通百通。反模式警示两个典型坏味道 ForOptionsBad.scala展示了用return提前退出处理Option的写法——虽然能工作但代码啰嗦、难以复用作者特意在注释里提醒看到return就该警惕这往往是重构信号。ForOptionsBad2.scala则用foldLeft加if判断硬算求和远不如for推导式干净。把这两个反面教材与前面的正例对比你会更直观地体会到推导式的价值。编程思想引用透明RefTransparency.scalaRefTransparency.scala对比了直接抛异常与返回Either两种错误处理方式。前者在表达式层面不透明后者则把成功/失败都当作普通值传递——这正是for推导式能优雅处理错误的前提。理解了引用透明你就理解了为什么 Scala 社区推崇用Option/Either/Try而非异常。实战应用登录表单校验LoginFormValidatorSingle.scala️仓库src/main/scala/progscala3/forcomps/下有一个完整的登录表单校验案例把理论用到了极致def apply(userName: String, password: String): E[ValidLoginForm] for _ - nonEmpty(userName, user name) _ - notTooShort(userName, user name, 5) _ - goodCharacters(userName, user name) _ - nonEmpty(password, password) _ - notTooShort(password, password, 5) _ - goodCharacters(password, password) yield ValidLoginForm(userName, password)六条校验规则像流水线一样串联任何一个不通过立即返回对应的Left错误全部通过才产出ValidLoginForm。LoginFormValidation.scala展示了数据建模LoginFormValidatorNec.scala则用Nec非空链版本累积返回所有错误而不是只报第一个——这是进阶必读。配合src/test/scala/progscala3/forcomps/下的ForOptionsGoodSuite.scala、ForEithersGoodSuite.scala等测试你可以验证每个示例的正确行为。快速上手如何运行这些示例克隆仓库后所有脚本示例都位于src/script/scala/progscala3/forcomps/目录可用 Scala 3 直接运行git clone https://gitcode.com/gh_mirrors/pr/programming-scala-book-code-examples cd programming-scala-book-code-examples scala-cli run src/script/scala/progscala3/forcomps/ForMap.scala学习路线建议先跑通入门基础 5 例 → 再看ForTranslated.scala理解展开原理 → 用 Option/Either/Try 三件套练手 → 最后精读登录表单校验把流水线式写法用到你自己的项目里。总结 ✍️programming-scala-book-code-examples中的这 20 个示例覆盖了for推导式的全部核心用法从最简转换、守卫过滤、副作用执行到Option/Either/Try的链式短路、模式过滤、反模式对比再到完整的登录校验实战。把这一组示例吃透你就掌握了 Scala 函数式编程中最实用的一招——写出的代码既简洁又健壮从此告别return满天飞的命令式写法。【免费下载链接】programming-scala-book-code-examplesThe code examples used in Programming Scala, 2nd and 3rd Editions (OReilly)项目地址: https://gitcode.com/gh_mirrors/pr/programming-scala-book-code-examples创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考