关于非空类型的辩论 [英] About the non-nullable types debate

查看:115
本文介绍了关于非空类型的辩论的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不断听到人们谈论非空引用类型如何解决这么多错误,并使编程变得如此容易。甚至null的创建者都将其称为十亿美元的错误规范#引入了不可空类型来解决此问题。

I keep hearing people talk about how non-nullable reference types would solve so many bugs and make programming so much easier. Even the creator of null calls it his billion dollar mistake, and Spec# has introduced non-nullable types to combat this problem.

编辑::忽略我对Spec#的评论。我误解了它的工作原理。

Ignore my comment about Spec#. I misunderstood how it works.

编辑2: ,我真的很希望有人与您争论:-)

EDIT 2: I must be talking to the wrong people, I was really hoping for somebody to argue with :-)

所以我猜,在少数派中,我错了,但我不明白为什么这场辩论有任何优点。我将null视为错误查找工具。请考虑以下内容:

So I would guess, being in the minority, that I'm wrong, but I can't understand why this debate has any merit. I see null as a bug-finding tool. Consider the following:

class Class { ... }

void main() {
    Class c = nullptr;
    // ... ... ... code ...
    for(int i = 0; i < c.count; ++i) { ... }
}

BAM!访问冲突。有人忘记初始化 c

BAM! Access violation. Someone forgot to initialize c.

现在考虑一下:

class Class { ... }

void main() {
    Class c = new Class(); // set to new Class() by default
    // ... ... ... code ...
    for(int i = 0; i < c.count; ++i) { ... }
}

糟糕。循环默默地跳过。可能需要一段时间才能找出问题所在。

Whoops. The loop gets silently skipped. It could take a while to track down the problem.

如果您的课程为空,则代码无论如何都会失败。为什么不让系统告诉您(尽管有点粗鲁)而不是自己弄清楚呢?

If your class is empty, the code is going to fail anyway. Why not have the system tell you (albeit slightly rudely) instead of having to figure it out yourself?

推荐答案

有点奇怪在该线程中标记为答案的响应实际上首先突出显示了null的问题,即:

Its a little odd that the response marked "answer" in this thread actually highlights the problem with null in the first place, namely:


我也发现了我的大多数NULL
指针错误都与
函数有关,而这是因为忘记检查string.h,
函数的
返回值,其中NULL被用作指示符。

I've also found that most of my NULL pointer errors revolve around functions from forgetting to check the return of the functions of string.h, where NULL is used as an indicator.

如果编译器可以在编译时而不是运行时捕获此类错误,那不是很好吗?

Wouldn't it be nice if the compiler could catch these kinds of errors at compile time, instead of runtime?

如果您使用过类似ML的语言(某种程度上是SML,OCaml,SML和F#)或Haskell,则引用类型是不可为空的。而是通过将其包装为选项类型来表示空值。这样,如果函数可以返回null作为合法值,则实际上可以更改其返回类型。因此,假设我想将用户拉出数据库:

If you've used an ML-like language (SML, OCaml, SML, and F# to some extent) or Haskell, reference types are non-nullable. Instead, you represent a "null" value by wrapping it an option type. In this way, you actually change the return type of a function if it can return null as a legal value. So, let's say I wanted to pull a user out of the database:

let findUser username =
    let recordset = executeQuery("select * from users where username = @username")
    if recordset.getCount() > 0 then
        let user = initUser(recordset)
        Some(user)
    else
        None

查找用户的类型为 val findUser:string->用户选项,因此该函数的返回类型实际上告诉您可以返回一个空值。要使用此代码,您需要同时处理Some和None情况:

Find user has the type val findUser : string -> user option, so the return type of the function actually tells you that it can return a null value. To consume the code, you need to handle both the Some and None cases:

match findUser "Juliet Thunderwitch" with
| Some x -> print_endline "Juliet exists in database"
| None -> print_endline "Juliet not in database"

如果您不能同时处理两种情况,则代码不会甚至编译。因此,类型系统保证您永远不会获得null引用异常,并保证始终处理null。如果函数返回 user ,则它保证是对象的实际实例。

If you don't handle both cases, the code won't even compile. So the type-system guarantees that you'll never get a null-reference exception, and it guarantees that you always handle nulls. And if a function returns user, its guaranteed to be an actual instance of an object. Awesomeness.

现在,我们在OP的示例代码中看到了问题:

Now we see the problem in the OP's sample code:

class Class { ... }

void main() {
    Class c = new Class(); // set to new Class() by default
    // ... ... ... code ...
    for(int i = 0; i < c.count; ++i) { ... }
}

已初始化和未初始化的对象具有相同的数据类型,您无法分辨它们之间的区别。有时,空对象模式可能有用,但是上面的代码表明编译器无法以确定您是否正确使用了类型。

Initialized and uninitialized objects have the same datatype, you can't tell the difference between them. Occasionally, the null object pattern can be useful, but the code above demonstrates that the compiler has no way to determine whether you're using your types correctly.

这篇关于关于非空类型的辩论的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆