【问题标题】:Why do we need the Option type when we have code contracts/static analysis?当我们有代码契约/静态分析时,为什么我们需要 Option 类型?
【发布时间】:2013-02-05 05:33:23
【问题描述】:

在设计一段 null 安全代码时,更好的方法是什么?

F# 和 Scala 有封装 null 检查的 Options 类型,但我们也有静态代码分析工具,如代码协定、findbugs。

对我来说,静态分析似乎更干净一些,那么 Option/Maybe 的原因是什么?特别是在防止 NullPointerExceptions/NullReferenceExceptions 方面有什么更好的方法?

【问题讨论】:

  • 嗯,首先,什么是选项类型?它如何与模式匹配和for一起使用? (选项不是关于“发现错误”,而是关于以一致的方式正确对问题建模;null 是 an unfortunate side-effect of ALGO 和 Java/JVM 借用的不幸方面,因此是 Scala。)跨度>
  • 我不认为这是一个“坏”的问题,但我认为它设置了不恰当的二元性。使用 Option/Maybe 并不排除其他工具;就像不排除测试一样。
  • @pst null 也是一种非常有效的方式来声明指针类型在任何允许接近硬件层的语言(汇编程序、C、C++)中无效,可能还有更多)。如果每个原始数字类型也都有一个空值,那就太好了,比如 Double.NAN
  • @ziggystar 我不同意。如何“null”在内部处理为没有公开它的语言(即语言only有可能代表像Haskell一样的“某事或无事”)是一个实现细节.例如,Java 实现使用 pointers,但 Java 中没有指针!没有理由必须“效率较低”。此外,案例 C# 显示,可以以最小的开销在原语上创建 Nullable 类型:但 .NET Nullable 类型不像 Option/Maybe 那样统一
  • @ziggystar 在这一点上,每一个具有 null 的“现代高级语言”都是没有解决这个问题的基本思想的结果。这就是 ALGO 的工作方式。这就是 C 的工作方式。这就是 Java 的工作方式。这就是 C# 的工作方式。它意味着这是最好的方法;它只是意味着它已经永久化了。

标签: scala f# null static-analysis code-contracts


【解决方案1】:

Option 用于模拟计算可能返回值的事实。它不只是为了封装空检查而存在;许多函数式编程语言,如 SML、Haskell 没有 null,但 Option/Maybe 是用于建模问题的有用工具。

对我来说静态分析似乎更干净一些,那么 Option/Maybe 的原因是什么?

在函数式编程的上下文中,使用静态分析来检查值的缺失是矫枉过正。静态类型检查可以做得很好(使用Option)。并且类型系统可以保证绝对正确,而静态分析工具可能会出现误报。

静态分析工具的另一个问题是成本高。构建它们(我不知道 F# 和 Scala 有什么好的静态分析工具)和使用它们(软件购买、开发人员培训)的成本很高。诚然,它们很强大,应该用于捕获更细微的错误(静态类型检查器无法捕获),例如索引越界、整数溢出等。

【讨论】:

  • +1 尽管推出了“Not Null”属性和其他此类“代码协定”,但可以公开/编码的信息远不止方法名称和参数(即使不是类型的一部分)自己).. 与 C# 等语言的 Visual Studio(+ 扩展)相比,Scala 工具很糟糕。就是这样:(
【解决方案2】:

Option 是一元的。一个主要的好处是透明地集成到一元计算链中,通常使用for 理解语法。

此外,我怀疑静态分析甚至可以在原则上避免测试是否存在值(Some / None 区别)。我的直觉是它相当于停止问题。

【讨论】:

  • 各种非空分析可以检测可证明非空和可能空并防止后者(除非它变成可证明非空值)——在这种情况下,两者都做不到或多或少)。一个只需要 Some 匹配(或映射或诸如此类),而另一个需要 if (x != null) { use(x) } .. 现在,如果 Scala 禁止null 用于 Option 类型并且 禁止 创建 Some(null),然后 .. 但两种方法都会遇到“边界”问题,只是方式不同。
  • 话虽这么说,第一段 +1 - 直到一个 使用 选项/也许是什么(而不是简单的“null-guard”),一个可以'不真正享受 Option/Maybe 类型的存在。
【解决方案3】:

一方面,静态分析只有在 API 被注释或完整的源代码/字节码可用时才能工作。

如果你有一个 API,但实现它的实际库将在运行时决定,静态分析是无能为力的。

另一方面,静态分析本质上是有限的。应用图灵完整性的限制,这意味着它无法确定某事是否在所有情况下都可能为空。

所以,这些都是静态分析的限制,不是选项类型所共有的,但是选项类型还有一个额外的优势:它们是 monad。这意味着您可以使用它们进行计算,而如果仅限于可空性的 if 检查,您将不得不求助于重复自己。

最后一个陈述可能不清楚,但它是事物的本质:如果您了解 monad 的使用方式,则无需进一步解释;如果你不这样做,那么解释对你没有多大帮助。学习使用 monad 的最好方法是使用它——真的和编程中的其他一切一样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 2015-10-23
    • 2023-01-24
    • 2021-11-05
    • 2015-07-11
    • 1970-01-01
    相关资源
    最近更新 更多