![]() |
1
422
我认为,为什么空值是不受欢迎的简单概括是 无意义的状态不应该是可表示的 . 假设我在做一扇门的模型。它可以处于三种状态之一:打开、关闭但未锁定,以及关闭和锁定。现在我可以按照
很清楚如何将我的三个状态映射成这两个布尔变量。但这就留下了第四种不受欢迎的状态:
然后我可以定义
不再有烦恼。类型系统将确保对于
问题在于
当您确实打算建模一个可能不存在的值时,那么您应该明确地选择它。如果我想塑造人们的方式是
哪里
例如,使用上面的类型,我们可以编写这个愚蠢的函数:
不用担心。相反,在一种语言中,对于字符串之类的类型具有可以为空的引用,然后假设
你最终创作的东西
如果传入的Person对象不具有所有非空的不变量,则会爆炸,或者
或者也许
假设
空通常会增加不必要的复杂性。 复杂性是所有软件的敌人,只要合理,您就应该努力降低复杂性。
(请注意,即使是这些简单的例子,也更复杂。即使是
|
![]() |
2
63
选项类型的好处不是它们是可选的。就是那个 不是所有其他类型的 . 有时 我们需要能够表示一种“空”状态。有时我们必须表示一个“无值”选项以及一个变量可能采用的其他可能值。因此,一种完全不允许这样做的语言将会有点残废。 但是 经常 我们不需要,而且 允许 这样的“空”状态只会导致歧义和混乱:每次我访问.NET中的引用类型变量时,我都必须考虑到 可能是空的 . 通常,它永远不会 事实上 为空,因为程序员构造代码以使其永远不会发生。但是编译器无法验证这一点,每次你看到它,你都必须问自己“这能是空的吗?”我需要在这里检查空值吗?” 理想情况下,在许多情况下,空值没有意义, 不应该允许这样做 . 在.NET中很难实现这一点,因为几乎所有内容都可以为空。你必须依赖于你所调用的代码的作者,使其100%的纪律性和一致性,并且清楚地记录了什么可以或不能为空,或者你必须偏执和检查 一切 . 但是,如果类型不可以为空 默认情况下 ,则不需要检查它们是否为空。您知道它们永远不能为空,因为编译器/类型检查器为您强制执行它。 然后我们就需要一个后门来处理罕见的案件 做 需要处理空状态。然后可以使用“选项”类型。然后我们允许空值出现在我们已经做出了一个有意识的决定的情况下,我们需要能够表示“无值”的情况,并且在其他情况下,我们知道值永远不会是空值。 正如其他人提到的,例如,在C语言或Java中,NULL可以指两件事情之一:
第二个意义必须保留,但第一个意义应该完全消除。即使第二个意思也不应该是默认的。这是我们可以选择的 如果我们需要的时候 . 但是当我们不需要可选的东西时,我们希望类型检查器 保证 它永远不会是空的。 |
![]() |
3
43
到目前为止,所有的答案都集中在为什么
然后他们继续建议,如果您对
全部的
值,如果添加类似
都是好东西!但它并不排除使用显式的可空/非空类型来实现相同的效果。那么,为什么选择仍然是一件好事?毕竟,scala支持可以为空的值(即
有
因此,它可以与Java库一起工作,但支持
Q. 那么,除了能够从语言中完全删除空值之外,还有什么好处呢? a. 作文 如果您从了解空值的代码进行幼稚的转换
到选项识别代码
没什么区别!但它也是 可怕的 使用选项的方式…这种方法要干净得多:
甚至:
当你开始处理选项列表时,它会变得更好。想象一下清单
这是怎么工作的?
带有空检查的相应代码(甚至是ELVIS?:operators)会非常长。这里真正的技巧是flatmap操作,它允许以一种不可为空值的方式嵌套理解选项和集合。 |
![]() |
4
38
因为人们似乎错过了它:
爱丽丝的出生日期是
鲍勃的死亡日期是
一个“合理”的解释可能是爱丽丝的出生日期存在,但未知,而鲍勃的死亡日期不存在(鲍勃仍然活着)。但是为什么我们得到不同的答案呢?
另一个问题:
答案是 通常 分别为“是”、“否”、“是”、“是”、“否”、“是”。疯狂的“数学家”称南为“虚无”,并说它比自己平等。SQL将空值视为不等于任何内容(因此它们的行为类似于NaN)。当您试图将±、±0和nan存储到同一个数据库列中时会发生什么情况(有2个 五十三 南,其中一半是“负的”)。 更糟的是,数据库处理空值的方式不同,而且大多数不一致(请参见 NULL Handling in SQLite 概述)。太可怕了。 现在,对于强制性的故事:
我最近设计了一个(sqlite3)数据库表,有五列
这尤其有效,因为在大多数数据库的唯一性约束中,空值是如何工作的(假设这样更容易模拟“真实世界”的情况,例如,没有两个人可以拥有相同的社会保险号,但并非所有人都有一个)。 FWWW,不首先调用未定义的行为,C++引用不能“指向”null,并且不可能构造具有未初始化的引用成员变量的类(如果抛出异常,则构造失败)。
旁注:有时您可能需要互斥指针(即只有一个指针可以是非空的),例如在假设的IOS中
|
![]() |
5
16
默认情况下,具有引用/指针的不可接受性为空。 我不认为这是空值的主要问题,空值的主要问题是它们有两个含义:
支持选项类型的语言通常也禁止或不鼓励使用未初始化的变量。 选项类型如何工作,包括易于检查空情况(如模式匹配)的策略。 为了有效,需要在语言中直接支持选项类型。否则,需要大量的锅炉板代码来模拟它们。模式匹配和类型推断是使选项类型易于使用的两个关键语言功能。例如: 在F中:
然而,在Java这样的语言中,如果没有直接支持选项类型,我们会有如下类似的情况:
其他解决方案,如消息吃零
Objective-C的“消息吃不到”并不是一个解决方案,而是一种减轻检查无效时头疼的尝试。基本上,在尝试对空对象调用方法时,表达式不会引发运行时异常,而是计算为空本身。挂起不信任,就好像每个实例方法都以
|
![]() |
6
11
汇编给我们带来了地址,也称为非类型指针。C直接将它们映射为类型指针,但引入了algol的空值作为唯一的指针值,与所有类型指针兼容。在C语言中,空值的一个大问题是,由于每个指针都可以为空,所以在没有手动检查的情况下,永远不能安全地使用指针。 在高级语言中,空值很难理解,因为它实际上传达了两个截然不同的概念:
拥有未定义的变量几乎是无用的,并且在任何时候都会导致未定义的行为。我想每个人都会同意,无论如何都要避免不明确的事情发生。 第二种情况是可选性,最好明确提供,例如 option type . 假设我们是一家运输公司,我们需要创建一个应用程序来帮助我们的司机创建一个时间表。对于每个司机,我们存储一些信息,例如:他们拥有的驾驶执照和紧急情况下要拨打的电话号码。 在C中,我们可以有:
正如您所观察到的,在对驱动程序列表进行任何处理时,我们都必须检查空指针。编译器不会帮助你,程序的安全依赖于你的肩膀。 在OCAML中,相同的代码如下所示:
现在假设我们要打印所有驾驶员的姓名以及他们的卡车牌照号码。 在C:
在OCAML中,这将是:
正如您在这个简单的示例中看到的,安全版本没有什么复杂的:
而在C语言中,你可能只是忘记了一个空的检查和繁荣… 注意:这些代码示例没有编译,但我希望您有想法。 |
![]() |
7
5
微软研究院有一个有趣的项目叫做
它是C扩展 非空类型 以及一些机制 检查对象是否不为空 但是,imho,应用 按合同设计 对于许多由空引用引起的麻烦情况,原则可能更合适,也更有用。 |
![]() |
8
3
罗伯特·尼斯特罗姆在这里提供了一篇很好的文章: http://journal.stuffwithstuff.com/2010/08/23/void-null-maybe-and-nothing/ 在为他的缺席和失败添加支持时描述他的思想过程 Magpie 程序设计语言。 |
![]() |
9
3
从.NET的背景来看,我一直认为空值有一个点,它很有用。直到我开始了解结构以及如何轻松地使用它们,从而避免使用大量样板代码。 Tony Hoare 2009年在伦敦Qcon演讲时, apologized for inventing the null reference . 引用他:
也看到这个问题 at programmers |
![]() |
10
1
我一直把空(或零)看作是 缺少值 . 有时你想要这个,有时你不想要。这取决于你正在工作的领域。如果缺席是有意义的:没有中间名,那么您的申请可以相应地采取行动。另一方面,如果空值不应该存在:名字是空的,那么开发人员会接到一个众所周知的2a.m.电话。
我还看到过代码过载和对空值的检查过于复杂。对我来说,这意味着两件事之一:
从积极的方面来看,空值可能是检查是否缺少某些东西的更有用的概念之一,而没有空值概念的语言在进行数据验证时,最终会使事情复杂化。在这种情况下,如果一个新变量没有初始化,那么languages通常会将变量设置为空字符串、0或空集合。但是,如果空字符串或0或空集合 有效值 对于您的应用程序——那么您有一个问题。 有时,通过为字段发明特殊/奇怪的值来表示未初始化的状态来规避这一点。但是当一个善意的用户输入特殊值时会发生什么呢?让我们不要陷入数据验证程序的混乱中。 如果语言支持空概念,那么所有的问题都将消失。 |
![]() |
11
0
矢量语言有时可以避免没有空值。 在这种情况下,空向量用作类型化的空向量。 |
![]() |
saber · MySql查询没有结果 3 年前 |
![]() |
pigfox · Mysql空表联接失败 7 年前 |
![]() |
Jaa Zaib · 返回空值的大小写表达式 7 年前 |
![]() |
Robert Vogelezang · 为什么null未写入输出窗口? 7 年前 |
![]() |
l. schwarz · sql长度(null) 7 年前 |
![]() |
ÇAÄrı Keskin · SQL-删除(消除)没有数据的列 7 年前 |
|
Dorkymon · 使用系统在输出处获取null。出来打印F 7 年前 |