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

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


当前回答

这并不是一个奇怪的特性,但从类型安全的角度来看,它确实令人恼火:c#中的数组协方差。

class Foo { }
class Bar : Foo { }
class Baz : Foo { }

Foo[] foo = new Bar[1];
foo[0] = new Baz(); // Oh snap!

我相信这是从Java继承而来的(双关语)。

其他回答

在awk中,数组从索引1开始,这是最不容易混淆的。

C / C + +:

快速平方根逆算法利用了IEEE浮点表示法(代码复制自维基百科):

float InvSqrt(float x)
{
    union {
        float f;
        int i;
    } tmp;
    tmp.f = x;
    tmp.i = 0x5f3759df - (tmp.i >> 1);
    float y = tmp.f;
    return y * (1.5f - 0.5f * x * y * y);
}

在Bash中,变量可以显示为标量和数组:

$ a=3
$ echo $a
3
$ echo ${a[@]}    # treat it like an array
3
$ declare -p a    # but it's not
declare -- a="3"
$ a[1]=4          # treat it like an array
$ echo $a         # acts like it's scalar
3
$ echo ${a[@]}    # but it's not
3 4
$ declare -p a
declare -a a='([0]="3" [1]="4")'
$ a=5             # treat it like a scalar
$ echo $a         # acts like it's scalar
5
$ echo ${a[@]}    # but it's not
5 4
$ declare -p a
declare -a a='([0]="5" [1]="4")'

KSH做同样的事情,但是使用排版而不是声明。

当你在zsh中这样做时,你得到的是子字符串赋值而不是数组:

$ a=3
$ a[2]=4          # zsh is one-indexed by default
$ echo $a
34
$ a[3]=567
$ echo $a
34567
$ a[3]=9
$ echo $a
34967
$ a[3]=123         # here it overwrites the first character, but inserts the others
$ echo $a
3412367
$ a=(1 2 3)
$ echo $a
1 2 3              # it's an array without needing to use ${a[@]} (but it will work)
$ a[2]=99          # what about assignments?
$ echo $a
1 99 3

在JavaScript中,2.0 - 1.1 = 0.8999999999999999。这是规范中实现浮点数的结果,所以它总是这样的。

在PHP中,你可以使用符号和字符串文字或包含变量名的变量引用变量,例如:

${'foo'} = 'test';
echo $foo;

这将打印“test”。这种行为的奇怪之处在于,你也可以使用非字符串作为变量名,例如:

${array()} = 'test';
echo ${array()};
${NULL} = 'test';
echo ${NULL};

现在我们有了名为array()的变量,甚至还有NULL!所有包含字符串"test"。