在你看来,你遇到过的最令人惊讶、最怪异、最奇怪或最“WTF”的语言特性是什么?

请每个回答只回答一个特征。


当前回答

Python for循环中的else。

来自Python文档:

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print n, 'equals', x, '*', n/x
            break
    else:
        # loop fell through without finding a factor
        print n, 'is a prime number'

输出:

2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

其他回答

大约20年前,当我最后一次涉足腮腺炎时,实现有一些奇怪的局限性。当主机MUMPS变得越来越流行时,MUMPS传统上是一种自托管语言:计算机语言、操作系统和数据库在一个包中。

腮腺炎主要是关于它的数据库。本质上,这是一个巨大的多维哈希表,由B*树支持,可以快速访问。语言和数据库之间也没有任何障碍:如果您想在那里存储一些东西,只需在变量前面加上一个符号,表明它将被持久化到备份存储中。

另一方面,文件系统几乎不存在,对它的支持就更少了。我们唯一能做的就是把一个程序从文件中加载到内存中,然后把内存中的内容发送回文件。最好在加载前清空缓冲区,否则它会和之前的东西混在一起。

因此,考虑到它的自托管性质和极其恶劣的文件系统,人们可能会想知道这些程序是如何编辑的。事实上,编辑器是用MUMPS本身编写的——那么,编辑器如何在不重写自己的情况下将程序存储在内存中呢?

好吧,诀窍在于能够以源代码的形式执行变量的内容。然后,编辑器将自己加载到变量中,在变量中执行自己,清除内存,然后在内存中加载、保存和编辑文件,一直从变量中执行。

除此之外,所有命令都可以被缩短为它们的第一个字母(除了Z命令,缩短为两个字母,主要处理文件系统),还有一个奇怪的事实,比如IF (I)设置了一个变量,然后由ELSE (E)查询——当然,可以被任何介入的I或程序本身覆盖。转念一想,我觉得整个语言就是个垃圾。然而,它有一种奇怪的吸引力。

有些奇怪——VBScript有一个Null关键字和一个Nothing关键字(Null是丢失的数据,Nothing是丢失的对象)。为什么不只有一个关键词…?大多数其他语言似乎都可以用一个!

Visual Basic 6.0当然还有“经典ASP”代码(因为它使用VBScript)也有同样的奇怪之处。在Visual Basic的新旧版本中,我们都有DBNull。

然而,这种情况正在改善,就像Visual Basic一样。NET Null终于消失了,所以Null不再使用,只有Nothing和DBNull被使用。

Haskell又说:

在Haskell中,你可以处理任意大小的文件,就好像它是一个简单的字符串。只有在实际使用字符串时,文件才会被读取。由于Haskell令人难以置信的懒惰,这样的程序将在恒定的空间中运行,而不管文件的大小:

main = interact (>>= \x -> if x == '\n' then "\r\n" else [x])

(这个程序将一个文件从stdin转换为stdout,并将LF替换为CRLF,交互函数将整个stdin输入到一个函数,并将输出移动到stdout。)

这种惰性也可能导致问题,因为如果关闭一个文件句柄,就不能完全shure,不管Haskell是否已经解析了其中的所有数据。

我最喜欢的c++之一:

#include <iostream>
using namespace std;
int main()
{
    cout <<  3 << 5  << endl;
    cout << (3 << 5) << endl;
    return 0;
}

当然,这很容易解释,但它让刚开始编程的学生摸不着头脑!

在JavaScript中,方法的结果取决于所放置的样式花括号。这是K&R风格,其中括号放在方法签名之后和return语句之后:

var foo = function() {
  return {
    key: 'value'
  };
}

foo() // returns an object here

现在,如果我将这段代码格式化为Allman风格,其中括号总是放在新行上,结果是不同的:

var foo = function()
{
  return
  {
    key: 'value'
  };
}

foo() // returns undefined here

如何来吗?在JavaScript中,如果您不自己做,语言会自动在每行末尾放置分号。所以在最后一个代码片段中真正发生的是这样的:

var foo = function()
{
  return; // here's actually a semicolon, automatically set by JavaScript!
  {
    key: 'value'
  };
}

因此,如果调用foo(),方法中的第一个语句将是一个返回语句,该语句将返回undefined,并且不会执行后面的其他语句。