使用spec/valid可以吗?在运行时进行函数输入验证?
Is it ok to use spec/valid? for function input validation at runtime?
我正在编写一个 clojure 库,我正在考虑使用 clojure.spec。使用 spec/valid 是一种好习惯吗?在运行时输入函数?还是我应该将解构与类型提示一起使用?我很担心,是否会有性能损失,是否被认为是对规范的不良使用,以及通常的不良做法。
检查有效输入总是合适的 "where appropriate"。那是什么意思?这是一个悬而未决的问题。
一般来说,最多 "dangerous" 的输入将来自外部世界,在您的程序边界。这意味着来自 web/browser 或可能来自其他服务的输入。
"safest" 输入在您的程序的深处,(大概)您有更多的控制权和信心。例如,您(可能)永远不会检查 +
函数的输入以确保每个参数都是一个数字。而且,即使有一个无效的参数(可能是一个字符串)漏掉了,JVM 也会立即抛出异常。
当然,您应该在 运行 单元测试时进行最大程度的检查,所以至少您知道您的代码在 "normal" 路径中正常工作。我喜欢为此使用 Plumatic Schema,因为在单元测试期间总是 运行 很容易进行验证,但在 "production" 运行 期间默认关闭。
话虽如此,我经常将 assert 语句放在函数的开头,这样错误的输入将难以识别,或者以后确实会导致难以诊断的问题。
这两种技术都救了我很多次!
请注意,即使是像 Java 这样的强类型语言也不会在这里拯救你。类型化变量可以确保输入是数字,但它可能无效,例如向 sqrt
函数发送负值。其他函数可能有更严格的输入,例如仅对质数有效等。类型无法捕获这些详细要求。只有良好的设计和良好的测试才能避免这些问题。
类型和断言不能防止所有问题,但它们就像路上的警卫rails(或安全带和安全气囊)。他们可能无法避免碰撞,但可以提供早期预警并降低后果的严重性。
P.S。您可以看到我喜欢如何平衡安全性和检查成本之间的权衡 a libary I wrote. Be sure to see the file _bootstrap.clj
这是仅在单元测试期间打开 Plumatic Schema 测试的技巧。
我正在编写一个 clojure 库,我正在考虑使用 clojure.spec。使用 spec/valid 是一种好习惯吗?在运行时输入函数?还是我应该将解构与类型提示一起使用?我很担心,是否会有性能损失,是否被认为是对规范的不良使用,以及通常的不良做法。
检查有效输入总是合适的 "where appropriate"。那是什么意思?这是一个悬而未决的问题。
一般来说,最多 "dangerous" 的输入将来自外部世界,在您的程序边界。这意味着来自 web/browser 或可能来自其他服务的输入。
"safest" 输入在您的程序的深处,(大概)您有更多的控制权和信心。例如,您(可能)永远不会检查 +
函数的输入以确保每个参数都是一个数字。而且,即使有一个无效的参数(可能是一个字符串)漏掉了,JVM 也会立即抛出异常。
当然,您应该在 运行 单元测试时进行最大程度的检查,所以至少您知道您的代码在 "normal" 路径中正常工作。我喜欢为此使用 Plumatic Schema,因为在单元测试期间总是 运行 很容易进行验证,但在 "production" 运行 期间默认关闭。
话虽如此,我经常将 assert 语句放在函数的开头,这样错误的输入将难以识别,或者以后确实会导致难以诊断的问题。
这两种技术都救了我很多次!
请注意,即使是像 Java 这样的强类型语言也不会在这里拯救你。类型化变量可以确保输入是数字,但它可能无效,例如向 sqrt
函数发送负值。其他函数可能有更严格的输入,例如仅对质数有效等。类型无法捕获这些详细要求。只有良好的设计和良好的测试才能避免这些问题。
类型和断言不能防止所有问题,但它们就像路上的警卫rails(或安全带和安全气囊)。他们可能无法避免碰撞,但可以提供早期预警并降低后果的严重性。
P.S。您可以看到我喜欢如何平衡安全性和检查成本之间的权衡 a libary I wrote. Be sure to see the file _bootstrap.clj
这是仅在单元测试期间打开 Plumatic Schema 测试的技巧。