Language agnostic 指针。许多编译器在尝试取消引用空指针时会陷入陷阱,如果向指针添加偏移量并尝试取消引用空指针,则不会陷入陷阱。在C标准中,尝试添加偏移量是未定义的行为,并且检查指针的性能代价不会比检查取消引用更糟糕(特别是如果编译器能够意识到,如果在添加偏移量之前检查指针是否为非空,那么之后可能不需要重新检查)

Language agnostic 指针。许多编译器在尝试取消引用空指针时会陷入陷阱,如果向指针添加偏移量并尝试取消引用空指针,则不会陷入陷阱。在C标准中,尝试添加偏移量是未定义的行为,并且检查指针的性能代价不会比检查取消引用更糟糕(特别是如果编译器能够意识到,如果在添加偏移量之前检查指针是否为非空,那么之后可能不需要重新检查),language-agnostic,null,language-design,nullable,Language Agnostic,Null,Language Design,Nullable,至于对不可为null的变量的语言支持,最好有一种方法,要求声明中包含初始值的某些变量或字段自动测试任何写入操作,以确保在尝试将null写入时立即发生异常。如果有一种有效的惯用方法来构造数组,即通过构造所有元素而不是在构造完成之前使数组对象本身可用,那么数组可以包含类似的特性。请注意,如果在构造所有元素之前发生异常,则可能还应该有一种方法指定对所有先前构造的元素调用的清理函数 最后,如果可以指定某些实例成员应通过非虚拟调用调用,并且即使在空项上也应可调用,这将非常有用。类似于String.IsNu

至于对不可为null的变量的语言支持,最好有一种方法,要求声明中包含初始值的某些变量或字段自动测试任何写入操作,以确保在尝试将null写入时立即发生异常。如果有一种有效的惯用方法来构造数组,即通过构造所有元素而不是在构造完成之前使数组对象本身可用,那么数组可以包含类似的特性。请注意,如果在构造所有元素之前发生异常,则可能还应该有一种方法指定对所有先前构造的元素调用的清理函数


最后,如果可以指定某些实例成员应通过非虚拟调用调用,并且即使在空项上也应可调用,这将非常有用。类似于
String.IsNullOrEmpty(someStringVariable)
的东西与
someStringVariable.IsNullOrEmpty

切换到函数式编程语言相比是可怕的;-)@杜邦:请把它作为一个回答。我添加了一个链接。当然,在C、爪哇或Python中,空的问题并不像C或C++那样大。然而,在这些语言中,仍然有大量的锅炉板代码专门用于空检查,并且开发人员花费了大量时间来跟踪空指针。当您认为可以在编译时通过添加一个额外的字符来避免它时,这有点愚蠢。空指针是危险的。不允许使用空对象引用;如果不使用null来表示未初始化的对象引用,则必须发明另一个sentinel值来提供相同的服务purpose@StevenLowe-要点是在不必要时(通常情况下)消除“未初始化状态”或sentinel的可能性。如果需要的话,你可以选择使用一个可为空的类型。你的第三段让我很困惑。你想避免自动解决常见问题,因为人类需要额外的工作来促进不“跳过步骤”的道德规范?是的,我同意布赖恩的观点。编译器投入了更多的工作,以提高开发人员的工作效率。实用主义而非理想主义。@Brian-我建议我们可以强迫开发人员声明某些变量可能为空,并且不会被检查,因为我们假设它不会为空,但这是我所能做的,因为这很难被滥用,如果它被滥用,很容易编写一个工具来检查所有的非检查并确定它们是否有效,例如,在代码复查中。@Jason-这很好,如果我们在编译器中放入了一些东西,我们应该可以很容易地知道意图是什么,这样就可以检查它了。但是,有太多的方法可以设置安全漏洞,开发人员需要更加谨慎,否则我们可能会禁止动态sql查询,并强制所有查询使用预先准备好的语句。@James Black:防止语言滥用几乎是不可能的。没有任何构造或工具可以拯救糟糕的程序员(除非砍掉他们的手指)。然而,代码契约是一个非常好的主意。不可为null的x.Prop应该设置为有意义的默认值或空值。API的使用者可以像以前一样重写它,但是从类型中知道他们不能将其设置为null。我认为不可为null的x.Prop应该保证在使用之前初始化。如果您需要一个“未初始化”状态,那么这就是null的用途,也许x.Prop实际上应该是可空的。+1 F#也支持选项类型,但不幸的是,它仍然必须考虑.NET framework中的null。我试图指出的一点是需要一个“未初始化”或“哨兵值”对于一个变量或参数来说是例外而不是规则。当需要时,我认为没有理由不使用“null”和可为null的形式(例如“MyType?”)。静态时间检查您是否访问未分配给“Guantees initialization”的对象,但不能保证不使用null(即它仍然可以初始化或稍后更改为null)。这些是不同的问题。如果您有一个永远不应该为null的方法参数,该怎么办?确保值不为null的静态检查正在使用不可为null的类型。手动检查null和处理NullReferenceException都很痛苦。不,可以使用类型。它们不必是…这是空对象模式吗?我没有考虑空模式,但选项类型:
MyClass notNullable = new MyClass();
notNullable = null; // Error!
// a la C#, where "T?" means "Nullable<T>"
MyClass? nullable = new MyClass();
nullable = null; // Allowed
x = new Foo()
x.Prop <- someInitValue
x.DoSomething()
x = new Foo(someInitValue)
x.DoSomething()
>>> let f = function  Some x -> x+1 | None->0 ;;
val f : int option -> int = <fun>
>>> f Some 5 ;;
- : int = 6
>>> f None ;;
- : int = 0
 >>> let f = function  Some x -> x+1 ;;
 Characters 8-31:
 let f = function  Some x -> x+1 ;;
         ^^^^^^^^^^^^^^^^^^^^^^^
 Warning P: this pattern-matching is not exhaustive.
 Here is an example of a value that is not matched:
 None
 val f : int option -> int = <fun>