racket - 禁止对使用 eval 的球拍中的特定功能进行类型检查
问题描述
我需要绕过特定函数的类型检查器,但让函数的类型签名可用于对程序的其他部分进行类型检查。我认为通常cast
会使用,但由于返回值的数量可变,这里失败了。
我将一个集合序列化为一个字符串,然后使用 eval 将其从字符串转换为再次设置。除了评估邪恶(我相信输入来源),我如何在打字球拍中处理这个问题?这就是我的实现:
(: string->set (-> String (Setof Symbol)))
(define (string->set s)
(eval (read (open-input-string s))))
这是类型检查器向我抛出的错误:
Type Checker: type mismatch;
; mismatch in number of values
; expected: 1 value
; given: unknown number
; in: (eval (read (open-input-string s)))
; [Due to errors, REPL is just module language, requires, and stub definitions]
我基本上需要让类型检查器:
- 不要尝试对这种方法进行类型检查,并且
- 相信当给定一个字符串参数时它返回一个集合的类型签名,并继续对其余代码进行类型检查。
我怎样才能做到这一点?
解决方案
这里有两个问题。首先,eval
, 返回多个值,而您的函数只返回一个。其次,在eval
返回的值中,每个值都有Any
类型,而您的函数承诺更具体的东西。
第一个问题可以用 来解决call-with-values
,它允许您将多个值转换为一个值(使用(lambda x x)
)。
第二个问题可以与cast
. 它会动态检查以确保类型适合,但否则可以让您动态地将值适合类型。
假设您知道该eval
语句只会返回一个值(或者您只关心返回的第一个值),您可以使用以下代码:
(: string->set (-> String (Setof Symbol)))
(define (string->set s)
(define ret
(first (call-with-values (λ () (eval (read (open-input-string s))))
(λ args args))))
(cast ret (Setof Symbol)))
nocheck
或者,您可以在 Typed Racket 中使用 use 。我建议不要这样做。因为它禁用了整个模块中的所有类型检查。
推荐阅读
- wordpress - 如何确保子主题 functions.php 正在运行
- rest - 如果用户想要对其个人资料和个人资料图片执行操作,客户端是否应该为 API 发送两个不同的 HTTP 请求
- excel - 在两个 Excel 实例之间复制值得到运行时错误 9
- java - 如何在 RecyclerView 中获取单击项目的位置
- terraform-provider-azure - 如何使用 Terraform 启用 Application Insights?
- python - Python Selenium:日期选择器选择日期
- python - 检查列表中的重复项时循环中断?
- excel - 如何在 OneDrive 和 applications.com.Excel 之间自动移动文件
- java - 当类中有hashMap时如何使用Gson从json文件中读取对象
- elasticsearch - 如何在 Kibana 查询中搜索 500 个词条