Racket中是否有类似上下文管理器的机制可自动关闭输入端口
Racket 网络端口自动关闭实现方案
Racket标准库原生提供了对齐call-with-input-file、Python with上下文管理器行为的资源安全调用过程,无需手动编写端口关闭指令,也不会出现异常场景下的端口泄漏问题。
改写后的地道实现
直接使用net/url内置的call/input-url过程即可,改写后代码如下:
#!/usr/bin/env racket #lang racket/base (require net/url racket/port) (require (planet neil/html-parsing:3:0)) (define my-html (call/input-url (string->url "https://www.rosettacode.org/wiki/Web_scraping") get-pure-port port->string))
逻辑说明
call/input-url的执行流程自带资源安全保障:- 接收URL对象、端口构造函数、端口处理函数三个核心参数
- 自动调用端口构造函数发起网络请求、打开输入端口
- 将可用端口传入处理函数执行业务读取逻辑
- 无论读取过程正常结束还是抛出网络、解析类异常,都会自动关闭已打开的网络端口,彻底避免端口残留
- 原手动关闭端口的写法存在逻辑漏洞:如果
port->string读取阶段触发异常,后续的close-input-port指令不会执行,会导致端口资源泄漏;call/input-url内部基于dynamic-wind实现资源回收,覆盖所有退出路径,安全性和call-with-input-file完全一致。 - 如果偏好块级的
with-*类语法,也可以基于call/input-url自行封装宏,日常直接调用该过程就是Racket网络请求的标准写法。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

