多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

安全异常处理新思路:programming-scala-book-code-examples 的 SaferExceptions 实验特性探索

安全异常处理新思路:programming-scala-book-code-examples 的 SaferExceptions 实验特性探索 安全异常处理新思路programming-scala-book-code-examples 的 SaferExceptions 实验特性探索【免费下载链接】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在 Java、Python 等主流语言里异常处理往往靠运行时兜底和程序员自觉异常到底会不会抛出、在哪里被捕获全靠经验判断。而programming-scala-book-code-examplesOReilly《Programming Scala》第三版的配套示例代码库中收录了一个非常前沿的尝试Scala 3 的安全异常处理实验特性 SaferExceptions。它尝试把抛出什么异常直接写进方法的类型签名里让编译器帮你检查异常是否被妥善处理为安全异常处理提供了一种全新的思路。本文将带你从零认识这个实验特性。什么是 SaferExceptions把异常写进类型的实验特性SaferExceptions 是 Scala 3.1 中引入的实验性能力目标是把异常抛出纳入类型系统方法声明自己可能抛出哪些异常调用方必须给出处理否则编译直接报错。这有点像 Java 的 checked exceptions受检异常但实现思路完全不同后面会详说。它目前只是实验特性所以示例代码都做了两件事一是文件顶部导入实验开关二是给使用它的对象或方法加上experimental注解。这两个示例没有收录在书里属于仓库作者额外补充的超前内容非常适合想尝鲜 Scala 新特性的读者。SaferExceptions 与 Java checked exceptions 有什么不同Java 的受检异常一直被吐槽传染性太强一个方法声明了受检异常所有调用它的方法都得跟着声明throws层层传递代码被异常声明淹没重构成本极高。SaferExceptions 的设计目标正是避免这些缺点异常声明只影响真正需要处理的地方编译器只在异常确实可能逃逸出作用域时报错而不是机械地要求每个调用方都写声明。无侵入式传播异常信息通过 Scala 3 的上下文参数using 子句在调用链中传递中间层无需额外改动。类型驱动、编译期检查处理不完整时编译直接失败把问题拦截在运行之前。简单说它想要 Java 受检异常的安全性又不要它的繁琐。如何启用安全异常处理一条 import 搞定启用方式非常轻量只需在源码中导入实验开关import language.experimental.saferExceptions不过要注意使用该特性的类型或方法还需要加上experimental注解这是 Scala 对实验性 API 的强制要求。在示例里作者特意用了object而非main方法正是因为编译器要求必须能对类型本身标注experimental。核心语法用 throws 声明可能抛出什么异常SaferExceptions 引入了一个全新的语法——方法签名末尾的throws子句。看仓库里的核心示例src/main/scala/progscala3/rounding/saferexceptions/SaferExceptions.scaladef openExistingFile(fileName: String): File throws IOException val file new File(fileName) if file.exists() false then throw new IOException(s$fileName doesnt exist!) filethrows IOException的含义一目了然这个方法可能抛出IOException。之后在main中调用它时编译器就会强制要求用try/catch处理IOException示例里也正是这样捕获并打印错误信息的。这段声明背后其实有一个等价的翻译File throws IOException等同于(using CanThrow[IOException])也就是说编译器通过注入的CanThrow能力来跟踪异常流向——这正是它区别于普通try/catch的机制所在。嵌套调用时异常如何自动传播SaferExceptionsNested更精彩的例子是src/main/scala/progscala3/rounding/saferexceptions/SaferExceptionsNested.scala它展示了异常在多层调用间的自动传播def wrapper(fileName: String): File throws IOException openExistingFile(fileName)wrapper调用了openExistingFile自己只是转手了一下并不真正处理异常于是它同样用throws IOException声明我把异常继续往上抛。编译器会沿着调用链逐层检查确保异常最终在某个层级被捕获——在这个例子里捕获逻辑依然在main的try/catch中完成。这正是 SaferExceptions 的优雅之处中间层只声明、不处理最外层统一兜底既保证了安全又不会像 Java 那样层层被迫处理异常。过渡期怎么用canThrowAny 临时放行实验特性刚上手时难免有逻辑还没写完、只想先跑通的时刻。为此 SaferExceptions 还提供了一个过渡用的注解unsafeExceptions.canThrowAny导入它之后可以暂时允许异常不受检查地抛出等把处理逻辑补齐后再删掉这行 import。源码注释里特别提醒记得在处理逻辑全部就位后移除这个导入否则安全异常处理就形同虚设了。对想要渐进式改造代码的团队来说这是一个非常贴心的过渡方案。如何运行这两个示例示例位于src/main/scala/progscala3/rounding/saferexceptions/目录下使用 sbt 运行即可命令格式如下sbt runMain progscala3.rounding.saferexceptions.SaferExceptions build.sbt badfile sbt runMain progscala3.rounding.saferexceptions.SaferExceptionsNested build.sbt badfile运行时会先编译再打印每个文件的字节大小对于不存在的文件则输出捕获到的IOException信息。你可以先 clone 整个仓库地址https://gitcode.com/gh_mirrors/pr/programming-scala-book-code-examples然后对照源码亲手跑一遍感受编译器盯着你处理异常的体验。小结SaferExceptions 用类型即文档的思路把安全异常处理从运行时人肉检查升级为编译期机器检查方法签名写明可能抛出的异常编译器沿调用链追踪处理不完整就编译失败。虽然它目前仍是实验特性语法和细节未来可能调整但方向非常值得关注——如果你正在学习 Scala 3不妨以这两个示例为起点提前感受下一代异常处理的形态。【免费下载链接】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),仅供参考
返回列表