在你看来,你遇到过的最令人惊讶、最怪异、最奇怪或最“WTF”的语言特性是什么?
请每个回答只回答一个特征。
在你看来,你遇到过的最令人惊讶、最怪异、最奇怪或最“WTF”的语言特性是什么?
请每个回答只回答一个特征。
当前回答
我为客户端编写了一种编程语言(用于实验驱动定制硬件),其中包含一些定制类型(Curl, Circuit,…),每种类型只有2个值。它们可以隐式地转换为布尔值,但是(在客户机的请求下)可以在运行时更改此类类型常量的确切布尔值。
例如: Curl类型有2个可能的值:CW和CCW(顺时针和逆时针)。在运行时,你可以通过一个简单的赋值语句改变布尔值:
ccw := true
所以你可以改变所有这些类型值的布尔值。
其他回答
ruby中的隐含变量\constants和可变常量
Java的访问修饰符对我来说是最近的一个WTF(因为我必须学习一点)。
显然,包比类层次结构更亲密。我不能定义对子类可见但对包中的其他类不可见的方法和属性。为什么我要将一个类的内部共享给其他类呢?
但是我可以定义对包内的每个类可见的属性和方法,但对包外的子类不可见。
不管我怎么想,我还是看不出其中的逻辑。切换访问修饰符,使受保护的行为就像它在c++中工作一样,并保持包的私有修饰符,这是有意义的。但现在不是了。
c#的默认继承模型赢得了我的投票:
public class Animal
{
public string Speak() { return "unknown sound" ; }
}
public class Dog : Animal
{
public string Speak() { return "Woof!" ; }
}
class Program
{
static void Main( string[] args )
{
Dog aDog = new Dog() ;
Animal anAnimal = (Animal) aDog ;
Console.WriteLine( "Dog sez '{0}'" , aDog.Speak() ) ;
Console.WriteLine( "Animal sez '{0}'" , anAnimal.Speak() ) ;
return ;
}
}
运行程序得到如下结果:
狗叫“汪!” 动物说“未知的声音”
获得这种行为应该要求程序员走出程序员的道路。子类实例不会因为被上转换为它的超类型而停止存在。相反,你必须显式地请求预期的(几乎总是想要的)结果:
public class Animal
{
public virtual string Speak() { return "unknown sound" ; }
}
public class Dog : Animal
{
public override string Speak() { return "Woof!" ; }
}
Forth的控制结构有些奇怪。首先,因为它是一种反向波兰符号语言,条件在IF之前,如:
x 0 = IF
现在,要关闭条件块,使用关键字THEN:
x 0 = IF ." Equals zero!" THEN
现在真正的WTF开始了。IF所做的是编译一个有条件的前向跳转,并将跳转偏移量的地址放在堆栈上。当找到THEN时,它从堆栈中弹出该地址,计算实际偏移量,然后编译它。另一方面,ELSE编译一个条件向前跳转,从堆栈中弹出一个地址,将一个新地址压入堆栈,计算弹出地址的偏移量,然后编译该偏移量。这意味着语法是这样的:
x 0 = IF ." Equals zero!" ELSE ." Not equal to zero!" THEN
第一个和第二个语句是这样编译的:
x LITERAL 0 = (0BRANCH) LITERAL offset SLITERAL" Equals zero!" (DOTQ)
x LITERAL 0 = (0BRANCH) LITERAL offset SLITERAL" Equals zero!" (DOTQ) BRANCH LITERAL offset SLITERAL" Not equal to zero!" (DOTQ)
更奇怪的是,这种行为并不隐藏。它是该语言的ANSI规范的一部分,可以通过构造自定义流控制结构或以有趣的方式组合它们来自由利用。例如,Forth的WHILE循环:
BEGIN x 10 < WHILE x 1+ to x REPEAT
BEGIN和WHILE之间的部分是任意代码,因此实际上可以在单个控制结构中让代码在条件测试之前和之后执行。这是故意的,但下面的内容虽然是允许的,但却不允许:
BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN
它利用了每个控制流字的工作方式来组合两个WHILE语句,并为每个出口添加不同的后循环代码来引导。为了表明我不是在开玩笑,我只是从互联网上的一个代码中复制了这个小片段,并进行了一些小的修改来简化它。
交替:在许多语言中的事物之间交替:
boolean b = true;
for(int i = 0; i < 10; i++)
if(b = !b)
print i;
乍一看,b怎么可能不等于它自己呢? 这实际上只会打印奇数