Programming languages 为什么不';我们不是有两个空的吗?
我经常想知道为什么带有表示“无值”的Programming languages 为什么不';我们不是有两个空的吗?,programming-languages,null,Programming Languages,Null,我经常想知道为什么带有表示“无值”的null的语言不区分被动的“我不知道值是什么”和更自信的“没有值” 在一些情况下,我希望将两者区分开来(特别是在处理用户输入和数据库时) 我想象如下,我们将两个状态命名为未知和空: var apple; while (apple is unknown) { askForApple(); } if (apple is null) { sulk(); } else { eatApple(apple); } 显然,我们可以通过手动将状态
null
的语言不区分被动的“我不知道值是什么”和更自信的“没有值”
在一些情况下,我希望将两者区分开来(特别是在处理用户输入和数据库时)
我想象如下,我们将两个状态命名为未知
和空
:
var apple;
while (apple is unknown)
{
askForApple();
}
if (apple is null)
{
sulk();
}
else
{
eatApple(apple);
}
显然,我们可以通过手动将状态存储在其他地方而不使用它
因此,如果我们可以有一个
null
,为什么不能有两个呢?在.net语言中,您可以使用,它解决了值类型的这个问题
但是,对于引用类型,问题仍然存在。由于.net中没有指针(至少在“安全”块中是这样),所以“object?o”不会编译。在大多数编程语言中,null表示“空”或“未定义”。另一方面,“未知”则有所不同。本质上,“未知”描述对象的状态。此状态必须来自程序中的某个位置
看一看这张照片。它可能会帮助您实现您想要实现的目标。javascript实际上既有null也有undefined(),但许多其他语言都没有。注意
null
是一种可接受但已知的条件。在我看来,未知状态是另一回事。我在帖子的评论部分与丹的对话将阐明我的立场。谢谢你,丹
您可能想要查询的是对象是否已初始化
Actionscript有这样一个东西(null
和未定义
)。但是有一些限制
见:
无效数据类型
void数据类型仅包含一个未定义的值。在ActionScript的早期版本中,未定义是对象类实例的默认值。在ActionScript 3.0中,对象实例的默认值为null。如果试图将未定义的值分配给对象类的实例,Flash Player或Adobe AIR会将该值转换为null。只能将未定义的值指定给未类型化的变量。非类型化变量是缺少任何类型注释或使用星号(*)符号进行类型注释的变量。只能将void用作返回类型注释
有一个空值还不够糟糕吗?在我的编程中,我最近采用了区分“语言空值”和“域空值”的做法 “语言null”是编程语言提供的特殊值,用于表示变量“无值”。它需要作为数据结构、参数列表和返回值中的伪值 “域空”是实现设计模式的任意数量的对象。实际上,每个域上下文都有一个不同的域null 对于程序员来说,使用语言null作为一个全包域null是相当常见的,但是我发现它会使代码更程序化(不太面向对象),并且更难辨别意图
每当想要一个空值时,问问自己:这是一个语言空值还是一个域空值?创建一个表示未知的静态常量非常容易,在极少数情况下,您需要这样的东西
var apple = Apple.Unknown;
while (apple == Apple.Unknown) {} // etc
,这似乎相当合理。毕竟,为什么要停在两个零位呢?为什么不是三个或四个等等,每个代表一个“无价值”状态
想象一下,如果被拒绝
,为空
,无效
:
var apple;
while (apple is refused)
{
askForApple();
}
if (apple is null)
{
sulk();
}
else if(apple is invalid)
{
discard();
}
else
{
eatApple(apple);
}
价值的存在:
- Python:
vars()。具有_键('variableName')
- PHP:
isset(变量)
- JavaScript:
typeof(变量)!='未定义的“
- Perl:
或者如果您愿意:(变量!=unde)
(定义变量)
当然,当变量未定义时,在PHP Strict中它不是空的,您需要对设置的变量执行
isset()
检查(否则会抛出警告)
Null类型是所有引用类型的子类型-您可以使用Null而不是对任何类型的对象的引用-这严重削弱了类型系统。它被认为是a中的一个,只存在于检查地址是否为零容易实现的情况下 至于为什么我们没有两个空值,是不是因为历史上在C语言中,空值是一个简单的
#define
而不是语言的一个独特部分?我认为有一个空值是处理基本模式的较低公分母
if thing is not NULL
work with it
else
do something else
在“做其他事情”部分,有很多种可能性,从“好吧,忘了它”到尝试在其他地方做“事情”。如果您不只是忽略空值的东西,您可能需要知道为什么“thing”是空的。如果有多种类型的NULL,将有助于您回答该问题,但可能的答案很多,正如这里的其他答案所暗示的。丢失的东西可能只是一个bug,可能是试图获取它时出错,可能现在不可用,等等。要决定哪些情况适用于您的代码——这意味着您必须处理它们——它是特定于域的。因此,最好使用应用程序定义的机制对这些原因进行编码,而不是找到一种语言功能来处理所有这些原因。问题在于,在强类型语言中,这些额外的空值应该包含有关类型的特定信息 基本上,额外的null是某种类型的元信息,可以依赖于类型的元信息 某些值类型具有此额外信息,例如许多数值类型具有NaN常量 在动态类型语言中,必须考虑无值引用(null)和类型可能为任何类型(未知或未定义)的变量之间的差异 例如,在静态类型C#中,类型为
if thing is not NULL
work with it
else
do something else
data MaybeEither a b = Object a
| Unknown b
| Null
deriving Eq
main = let x = Object 5 in
if x == (Unknown [2]) then putStrLn ":-("
else putStrLn ":-)"
AppleInformation appleInfo;
while (appleInfo is null)
{
askForAppleInfo();
}
Apple apple = appleInfo.apple;
if (apple is null)
{
sulk();
}
else
{
eatApple(apple);
}
boolean getAnswer() throws Mu