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

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


当前回答

大约在1977年,我在Lisp中添加了“format”函数,那时“printf”甚至还不存在(我是从与Unix相同的源:Multics复制的)。它一开始很无辜,但后来被一个接一个的特征填满了。当Guy Steele引入迭代和相关特性时,事情就失控了,这些特性被Common Lisp X3J13 ANSI标准所接受。下面的示例可以在Common Lisp The Language, 2nd Edition第22.3.3节中的表22-8中找到:

(defun print-xapping (xapping stream depth)
  (declare (ignore depth))
  (format stream
      "~:[{~;[~]~:{~S~:[->~S~;~*~]~:^ ~}~:[~; ~]~ ~{~S->~^ ~}~:[~; ~]~[~*~;->~S~;->~*~]~:[}~;]~]"
      (xectorp xapping)
      (do ((vp (xectorp xapping))
           (sp (finite-part-is-xetp xapping))
           (d (xapping-domain xapping) (cdr d))
           (r (xapping-range xapping) (cdr r))
           (z '() (cons (list (if vp (car r) (car d)) (or vp sp) (car r)) z)))
          ((null d) (reverse z)))
      (and (xapping-domain xapping)
           (or (xapping-exceptions xapping)
           (xapping-infinite xapping)))
      (xapping-exceptions xapping)
      (and (xapping-exceptions xapping)
           (xapping-infinite xapping))
      (ecase (xapping-infinite xapping)
        ((nil) 0)
        (:constant 1)
        (:universal 2))
      (xapping-default xapping)
      (xectorp xapping)))

其他回答

在c#中,为什么这是不合法的?

public class MyClass<T>
    where T: Enum
{

}

能够在Enum上添加扩展方法以及Func<T>是非常酷的,其中T将是您正在扩展的Enum,以便您可以对该Enum进行类型推断。

回复评论:是的,你可以扩展一个实际的枚举,但这里有区别:

你可以这样做:

public static void DoSomethingWithEnum(this Enum e)
{
   //do whatever
}

但是如果你想用你的方法获取一个Func,它将是你的enum的相同类型:

public static void DoSomethingWithEnum<T>(this T e, Func<T,bool> func )
   where T: Enum
{
   //do whatever
}

这样,你就可以像这样调用你的方法:

DayOfWeek today = DayOfWeek.Monday;
today.DoSomethingWithEnum(e => e != DayOfWeek.Sunday);

或者类似的东西。你懂的…这是不可能的,我也不知道为什么……

大约在1977年,我在Lisp中添加了“format”函数,那时“printf”甚至还不存在(我是从与Unix相同的源:Multics复制的)。它一开始很无辜,但后来被一个接一个的特征填满了。当Guy Steele引入迭代和相关特性时,事情就失控了,这些特性被Common Lisp X3J13 ANSI标准所接受。下面的示例可以在Common Lisp The Language, 2nd Edition第22.3.3节中的表22-8中找到:

(defun print-xapping (xapping stream depth)
  (declare (ignore depth))
  (format stream
      "~:[{~;[~]~:{~S~:[->~S~;~*~]~:^ ~}~:[~; ~]~ ~{~S->~^ ~}~:[~; ~]~[~*~;->~S~;->~*~]~:[}~;]~]"
      (xectorp xapping)
      (do ((vp (xectorp xapping))
           (sp (finite-part-is-xetp xapping))
           (d (xapping-domain xapping) (cdr d))
           (r (xapping-range xapping) (cdr r))
           (z '() (cons (list (if vp (car r) (car d)) (or vp sp) (car r)) z)))
          ((null d) (reverse z)))
      (and (xapping-domain xapping)
           (or (xapping-exceptions xapping)
           (xapping-infinite xapping)))
      (xapping-exceptions xapping)
      (and (xapping-exceptions xapping)
           (xapping-infinite xapping))
      (ecase (xapping-infinite xapping)
        ((nil) 0)
        (:constant 1)
        (:universal 2))
      (xapping-default xapping)
      (xectorp xapping)))

在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测试用例,比较了这些替代方案的性能。

在C语言中,数组可以像这样被索引:

a[10]

这很常见。

然而,鲜为人知的形式(真正有效!)是:

10[a]

这与上面的意思相同。

c++中我最喜欢的一个是“公共抽象具体内联析构函数”:

class AbstractBase {
public:
    virtual ~AbstractBase() = 0 {}; // PACID!

    virtual void someFunc() = 0;
    virtual void anotherFunc() = 0;
};

我是从Scott Meyers的《Effective c++》中偷来的。看到一个方法既是纯虚拟的(通常意味着“抽象”),又是内联实现的,这看起来有点奇怪,但这是我发现的确保对象被多态破坏的最佳和最简洁的方法。