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

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


当前回答

一个意想不到的特性是,在C、c#、Ruby等语言中,枚举定义列表和数组初始化列表中的末尾逗号。

string[] foods = { "tofu", "grits", "cabbage", }

public enum ArtPeriod {
  Modern,
  Romantic,
  Dada,
}

其他回答

Java的访问修饰符对我来说是最近的一个WTF(因为我必须学习一点)。

显然,包比类层次结构更亲密。我不能定义对子类可见但对包中的其他类不可见的方法和属性。为什么我要将一个类的内部共享给其他类呢?

但是我可以定义对包内的每个类可见的属性和方法,但对包外的子类不可见。

不管我怎么想,我还是看不出其中的逻辑。切换访问修饰符,使受保护的行为就像它在c++中工作一样,并保持包的私有修饰符,这是有意义的。但现在不是了。

在JavaScript中,你可以使用双位负(~~n)来代替Math.floor(n)(如果n是正数)或parseInt(n, 10)(即使n是负数)。N | N和N & N总是得到和~~ N相同的结果。

var n = Math.PI;
n; // 3.141592653589793
Math.floor(n); // 3
parseInt(n, 10); // 3
~~n; // 3
n|n; // 3
n&n; // 3

// ~~n works as a replacement for parseInt() with negative numbers…
~~(-n); // -3
(-n)|(-n); // -3
(-n)&(-n); // -3
parseInt(-n, 10); // -3
// …although it doesn’t replace Math.floor() for negative numbers
Math.floor(-n); // -4

单个位的求反(~)计算-(parseInt(n, 10) + 1),因此两个位的求反将返回-(-(parseInt(n, 10) + 1) + 1)。

更新:这里有一个jsPerf测试用例,比较了这些替代方案的性能。

这缺少了一个奇怪的特性:Python没有switch语句(尽管存在变通方法)。

C和c++中的三联体。

int main() {
   printf("LOL??!");
}

这将打印LOL|,因为trigraph ??!转换为|。

JavaScript八进制转换“特性”是一个很好的了解:

parseInt('06') // 6
parseInt('07') // 7
parseInt('08') // 0
parseInt('09') // 0
parseInt('10') // 10

详情请点击这里。