clojure - 可以使用规范/有效吗?在运行时进行函数输入验证?
问题描述
我正在编写一个 clojure 库,并且正在考虑使用 clojure.spec。使用规范/有效是一种好习惯吗?在运行时输入函数?还是我应该使用破坏性和类型提示?我担心,是否会有性能损失,是否被认为是对规范的不当使用,以及通常是不好的做法。
解决方案
在“适当的地方”检查有效输入总是合适的。这意味着什么?这是一个悬而未决的问题。
一般来说,最“危险”的输入将来自外部世界,位于程序的边界。这意味着来自网络/浏览器的输入,或者可能来自另一个服务。
“最安全”的输入在你的程序深处,在那里(大概)你有更多的控制和信心。例如,您(可能)永远不会检查+
函数的输入以确保每个 arg 都是数字。而且,即使一个无效的参数(可能是一个字符串)溜过,JVM 也会立即抛出一个异常。
当然,您应该在运行单元测试时进行最大程度的检查,因此至少您知道您的代码在“正常”路径中正常工作。我喜欢为此使用Plumatic Schema,因为在单元测试期间始终运行验证很容易,但在“生产”运行期间默认关闭。
话虽如此,我经常将断言语句放在函数的开头,其中错误的输入将难以识别或以后确实会导致难以诊断的问题。
这两种技术都救了我很多次!
请注意,即使是像 Java 这样的强类型语言也无法将您保存在这里。类型化变量可以确保输入是数字,但它可能是无效的,例如向函数发送负值sqrt
。其他函数可能有更严格的输入,例如仅对素数有效等。类型无法捕获这些详细要求。只有好的设计和好的测试才能避免这些问题。
类型和断言不能防止所有问题,但它们就像道路上的护栏(或安全带和安全气囊)。它们可能无法防止碰撞,但它们可以提供早期预警并降低后果的严重性。
PS 你可以看到我喜欢在安全性和签入我编写的库的成本之间取得平衡。请务必查看文件_bootstrap.clj
,这是仅在单元测试期间打开 Plumatic Schema 测试的技巧。
推荐阅读
- python - nltk wordpunct_tokenize 与 word_tokenize
- python - 使用前面的美元符号格式化右对齐数字
- django - 为什么分页不适用于 GenericAPIView?
- cordova - Cordova build ios - 说不是cordova项目
- c++ - 是否有跨平台的方法来禁用 C++ 中已弃用的警告?
- swift - 如何以编程方式滚动 NSScrollView?
- sql - GET all parent resource 的响应体是否应该返回一个子资源列表?
- android - Superpowered SDK Recorder 是否会绕过 Android 操作系统上的音频处理?
- c++ - 家长访问孩子
- javascript - 合并更多相似的JS函数