英文:
Historical reference on why Go creators choose to not treat `nil` as `false`
问题
为什么Go语言的创建者选择不将nil
视为false
?为什么他们认为明确比较值与nil
更好?是否有可靠的来源可以解释为什么Go语言这样设计?他们的观点是什么?这个决策背后的逻辑是什么?
我正在寻找一个历史参考。
例如:
f, err := os.Open(name)
if err != nil {
return err
}
而不是像其他许多语言那样将nil
隐式转换为false
:
f, err := os.Open(name)
if err {
return err
}
目前,后者会报错:
non-bool err (type error) used as if condition
英文:
Why did Go creators choose to not treat nil
as false
? What why did they think it is better to explicitly compare values to nil
? Is there a reliable source that would explain why is that is Go? What was their opinion? What was the logic behind this decision?
I'm looking for a historical reference.
E.g.:
f, err := os.Open(name)
if err != nil {
return err
}
Than to implicitly cast nil
s to false
like in many other languages:
f, err := os.Open(name)
if err {
return err
}
As of now, the latter would give:
non-bool err (type error) used as if condition
答案1
得分: 12
一些语言这样做会引起很多问题。这主要违反了最小惊讶原则。其中一些问题包括:
- 所有非空值都会被评估为
true
。指向false
布尔值的指针将被评估为true
。所有这些都会引发新的、更复杂的问题,也就是更多的错误。 - 将布尔值赋值为
nil
将是有效的。将布尔值与nil
进行比较也是有效的。这会造成语义混淆。更多的错误。 - 代码会变得更难阅读,因为它隐藏了意图。从表达式中无法判断你是想检查布尔值的值,还是断言其他类型变量的“非空性”。更多的错误。
- 在表达式中省略比较操作数也可以编译通过,这使得识别错误变得更加困难。想想那种你忘记添加比较操作而导致
b
始终评估为true
的情况,即使这不是你的本意。越来越多的错误。
Go语言的开发者可能考虑到了这些问题,并认为代码中错误较少的情况更好。
不过,也可以通过将错误传递给调用者来简化处理,例如:
require f := os.Open(name)
// 如果调用返回错误,返回错误
编辑:我很高兴地报告,Go团队正在考虑我提出的一个非常类似的方法,在Go 2中。只是他们使用了关键字check
:
check f := os.Open(name)
// 如果调用返回错误,运行声明的错误处理程序
// 这个处理程序可以返回错误或者对错误进行其他处理。
英文:
Some languages did that and it caused too many problems. It's primarily a violation of principle of least surprise. Some of the problems are:
- All non-nil values would evaluate to
true
. A pointer tofalse
boolean value would evaluate totrue
. All of that would create new and larger set of complications, aka more bugs. - Assigning a boolean to
nil
would be valid. Comparing a boolean tonil
would be valid. That creates a semantic confusion. More bugs. - Code would be harder to read because it hides the intent. It's impossible to tell from an expression if you want to check a boolean's value or assert "non-nilness" of some other type of variable. More bugs.
- Omitted operands in comparison operations in expressions would compile fine, making identifying bugs harder. Think about
if a == '3' && b { .. }
kind of cases where you forget to add the comparison sob
always evaluates totrue
even if it's not what you intend. More and more bugs.
Go people probably thought about it and preferred code with less bugs is better.
There could be a shortcut though just to propagate the error to the caller such as:
require f := os.Open(name)
// if the call returns error, return error
EDIT: I'm happy to report that Go team is considering a very similar approach to what I suggested, in Go 2. Only they used the keyword check
instead:
check f := os.Open(name)
// if the call returns error run the declared error handler
// which in turn, can return the error or do something else about it.
答案2
得分: 1
尽管我在任何golang文档或开发者讨论中都找不到确切的原因,但最接近的原因是,空值(nil)不应该被解释为假。这也符合golang是一种非常有主见的语言的事实,它的作者认为在评估真/假时不进行类型转换会导致更高质量的代码。
英文:
While I can't find an exact reason in any of the golang documentation or developer discussions, the closest reason is simply that that absence of a value (nil) should not be interpreted as false. This is also in line with the fact that golang is a very opinionated language, and that its authors felt that not casting types when evaluating for true/false would lead to better quality of code.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论