在你看来,你遇到过的最令人惊讶、最怪异、最奇怪或最“WTF”的语言特性是什么?
请每个回答只回答一个特征。
在你看来,你遇到过的最令人惊讶、最怪异、最奇怪或最“WTF”的语言特性是什么?
请每个回答只回答一个特征。
当前回答
Python 2. x
>>>True = False
>>>True
False
你真的可以让一个人变得疯狂。
其他回答
INTERCAL可能是最奇怪的语言特征的最佳汇编。我个人最喜欢的是COMEFROM语句,它(几乎)与GOTO相反。
COMEFROM is roughly the opposite of GOTO in that it can take the execution state from any arbitrary point in code to a COMEFROM statement. The point in code where the state transfer happens is usually given as a parameter to COMEFROM. Whether the transfer happens before or after the instruction at the specified transfer point depends on the language used. Depending on the language used, multiple COMEFROMs referencing the same departure point may be invalid, be non-deterministic, be executed in some sort of defined priority, or even induce parallel or otherwise concurrent execution as seen in Threaded Intercal. A simple example of a "COMEFROM x" statement is a label x (which does not need to be physically located anywhere near its corresponding COMEFROM) that acts as a "trap door". When code execution reaches the label, control gets passed to the statement following the COMEFROM. The effect of this is primarily to make debugging (and understanding the control flow of the program) extremely difficult, since there is no indication near the label that control will mysteriously jump to another point of the program.
其他奇怪的事情:
在c++中,覆盖一个虚方法会隐藏该方法的所有其他重载。在Java中,这种情况不会发生。这很烦人。例如:http://codepad.org/uhvl1nJp
在c++中,如果基类有一个公共虚方法foo(),子类有一个私有方法foo(),这个私有方法会覆盖另一个方法! 这样,只需将子类对象指针强制转换为父类对象指针,就可以在类外部调用私有方法。这不应该是可能的:这违反了封装。新方法不应被视为对旧方法的重写。例如:http://codepad.org/LUGSNPdh
在PHP中,你可以定义函数来接受类型化参数(例如,对象是某个接口/类的子类),讨厌的是,在这种情况下,你不能使用NULL作为实际的参数值。 例如:http://codepad.org/FphVRZ3S
在Java中从文本文件中读取一行。
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("filename"));
String str;
str = in.readLine();
if (str != null) {
...
}
} catch (IOException e) {
...
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {}
}
啊。虽然我承认这并不奇怪……只是邪恶。: -)
更短、更习惯的版本:
try {
BufferedReader in = new BufferedReader(new FileReader("filename"));
try {
String str = in.readLine();
while (str != null) {
str = in.readLine();
}
} finally {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
在我看来,这在c++中是不允许的:
class A {
public:
virtual string foo(){return "A::foo";}
};
class B : public A {
public:
virtual string foo(){return "B::foo";}
};
int main () {
B* b = new B();
// In my opinion the following should not be allowed
cout << b->A::foo() << endl; // Will print "A::foo"
}
这似乎是正确的,但这意味着如果不允许子类的用户调用原始方法而不是新方法,就不能重写方法。
只要考虑一个集合的子类,当向集合本身添加一个元素时,您希望增加元素的数量。
一个合乎逻辑的解决方案是重写add()方法,在添加元素之前增加计数器,但是新集合的用户可以使用旧方法向其添加元素,这样就绕过了增量,导致元素计数器与集合的实际元素数量不一致。
这在Java中是不可能的。
在JavaScript中,下面的构造
return
{
id : 1234,
title : 'Tony the Pony'
};
返回undefined是一个语法错误,因为在返回后的换行上偷偷地插入了分号。以下工作正如你所期望的那样:
return {
id : 1234,
title : 'Tony the Pony'
};
更糟糕的是,这个也可以(至少在Chrome中):
return /*
*/{
id : 1234,
title : 'Tony the Pony'
};
下面是同一个问题的一个变种,它不会产生语法错误,只是无声地失败了:
return
2 + 2;