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

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


当前回答

在c++中,“虚”MI(多重继承)允许“菱形”类层次结构“工作”,这让我觉得奇怪和讨厌。

A:基类,例如:“对象” B, C:两者都(实际上或不是)源于对象和 D:起源于B和C

问题:“正常”继承导致D是2种不明确的A。“虚拟”MI将B的A和C的A折叠为一个共享基对象A。

所以,即使你的车轮是一个对象,你的左前轮是一个车轮,你的汽车继承了四种车轮,你的汽车仍然只是一种具有虚拟MI的对象。否则,你的汽车不是一个对象,而是4个车轮对象。

这是一种奖励糟糕的类设计、惩罚编译器编写者的语言特性,并让您在运行时怀疑对象到底在哪里——以及是否有任何虚拟MI行李放错了地方。

如果在类层次结构中确实需要菱形模式,可以使用常规MI和委托给单个A基的“AProxy”来完成。

A:基类,例如:“对象” AProxy:基类,与其他A绑定的构造 B:源自A C:来源于AProxy D:源自B和C(在构造时将B的A传递给C的AProxy)

对于那些真正喜欢diamond MI的人来说,这需要做更多的工作,而我们其他人则可以安心地使用一组更易于处理的语言特性。

其他回答

这并不奇怪或令人惊讶,但这让我总是说WTF:

语法或标识符名称的大小写敏感性。

大多数具有它的语言似乎只是因为C具有它。这样做没有什么好的理由。

试试吧,除非,否则

try:     pass
except:  pass
else:    pass
finally: pass

如果没有捕获异常,则执行else部分。

有道理,但一开始我真的不知道它是干什么的。

例子:

def show_square(string):
  try:
    n = int(string, 10)
  except ValueError:
    print "I can't do that, Dave."
  else:
    print n * n

Haskell's use of Maybe and Just. Maybe a is a type constructor that returns a type of Just a, but Maybe Int won't accept just an Int, it requires it to be a Just Int or Nothing. So in essence in haskell parlance Just Int is about as much of an Int as an apple is an orange. The only connection is that Just 5 returns a type of Maybe Interger, which can be constructed with the function Just and an Integer argument. This makes sense but is about as hard to explain as it can theoretically be, which is the purpose of haskell right? So is Just really JustKindaLikeButNotAtAll yea sorta, and is Maybe really a KindaLooksLikeOrIsNothing, yea sorta again.

-- Create a function that returns a Maybe Int, and return a 5, which know is definitly Int'able
>  let x :: Maybe Int; x = 5;
<interactive>:1:24:
    No instance for (Num (Maybe Int))
      arising from the literal `5' at <interactive>:1:24
    Possible fix: add an instance declaration for (Num (Maybe Int))
    In the expression: 5
    In the definition of `x': x = 5

>  Just 5  
Just 5
it :: Maybe Integer

    -- Create a function x which takes an Int
>  let x :: Int -> Int; x _ = 0;
x :: Int -> Int
-- Try to give it a Just Int
>  x $ Just 5                   

<interactive>:1:4:
    Couldn't match expected type `Int' against inferred type `Maybe t'
    In the second argument of `($)', namely `Just 5'
    In the expression: x $ Just 5
    In the definition of `it': it = x $ Just 5

祝你好运读到这篇文章,我希望它是正确的。

在C语言中,sizeof操作符不计算其实参。这允许编写看起来错误但实际上是正确的代码。例如,给定类型T,调用malloc()的惯用方法是:

#include <stdlib.h>

T *data = NULL;
data = malloc(sizeof *data);

这里,*data在sizeof操作符中不被求值(data是NULL,所以如果它被求值,就会发生糟糕的事情!)。

这使得人们能够编写令人惊讶的代码,无论如何,对于新手来说。请注意,没有哪个头脑正常的人会这么做:

#include <stdio.h>

int main()
{   
    int x = 1;
    size_t sz = sizeof(x++);
    printf("%d\n", x);
    return 0;
}   

输出1,而不是2,因为x永远不会增加。

对于sizeof的一些真正的乐趣/困惑:

#include <stdio.h>
int main(void)
{
    char a[] = "Hello";
    size_t s1 = sizeof a;
    size_t s2 = sizeof ("Hi", a);
    printf("%zu %zu\n", s1, s2);
    return 0;
}

(只有当人们对数组、指针和操作符感到困惑时才会出现这种困惑。)

在JavaScript(和Java)中,你可以转义这样有趣的字符:

var mystring = "hello \"world\"";

如果你想把回车放到字符串中,那是不可能的。你必须像这样使用\n:

var mystring = "hello, \nworld";

这是正常的,也是意料之中的——至少对于一种编程语言来说。奇怪的是你也可以像这样转义一个实际的回车:

var mystring = "hello, \
world";