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

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


当前回答

PHP中的变量

PHP中一个奇怪的特性,它允许你从其他变量的内容中创建和分配变量(警告,未经测试的代码):

$a = 'Juliet';
$$a = 'awesome'; // assigns a variable named $Juliet with value 'awesome'

echo '$a';       // prints Juliet
echo '${$a}';    // prints awesome
echo '$Juliet';  // prints awesome

好吧,假设我们有这样的东西:

$bob = 'I\'m bob';
$joe = 'I\'m joe';
$someVarName = 'bob';
$$someVarName = 'Variable \'bob\' changed';

用各种间接的方式来找点乐子怎么样:

$juliet = 'Juliet is awesome!';
$func = 'getVarName'

echo '${$func()}'; // prints 'Juliet is awesome!'

function getVarName() { return 'juliet'; }

其他回答

PHP

PHP对实例变量和方法的重载处理不一致。考虑:

class Foo
{
    private $var = 'avalue';

    private function doStuff()
    {
        return "Stuff";
    }

    public function __get($var)
    {
        return $this->$var;
    }

    public function __call($func, array $args = array())
    {
        return call_user_func_array(array($this, $func), $args);
    }
}

$foo = new Foo;
var_dump($foo->var);
var_dump($foo->doStuff());

转储$var是有效的。即使$var是私有的,__get()也会被任何不存在或不可访问的成员调用,并返回正确的值。这不是doStuff()的情况,它失败于:

Fatal error: Call to private method Foo::doStuff() from context ”.”

我认为其中很多都是在c风格的语言中工作的,但我不确定。

Pass a here document as a function argument: function foo($message) { echo $message . "\n"; } foo(<<<EOF Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc blandit sem eleifend libero rhoncus iaculis. Nullam eget nisi at purus vestibulum tristique eu sit amet lorem. EOF ); You can assign a variable in an argument list. foo($message = "Hello"); echo $message; This works because an assignment is an expression which returns the assigned value. It’s the cause of one of the most common C-style bugs, performing an assignment instead of a comparison.

Python

在Python中,可变的默认函数参数会导致意想不到的结果:

def append(thing, collection=[]):
    collection.append(thing)
    return collection

print append("foo")
# -> ['foo']
print append("bar")
# -> ['foo', 'bar']
print append("baz", [])
# -> ['baz']
print append("quux")
# -> ['foo', 'bar', 'quux']

空列表是在函数定义时初始化的,而不是在调用时初始化的,因此对它的任何更改都会在函数调用之间保持不变。

MySQL的大小写敏感性

MySQL有非常不寻常的区分大小写的规则:表区分大小写,列名和字符串值不区分大小写:

mysql> CREATE TEMPORARY TABLE Foo (name varchar(128) NOT NULL);
DESCRIBE foo;
ERROR 1146 (42S02): Table 'foo' doesn't exist
mysql> DESCRIBE Foo;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| name  | varchar(128) | NO   |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
1 row in set (0.06 sec)
mysql> INSERT INTO Foo (`name`) VALUES ('bar'), ('baz');
Query OK, 2 row affected (0.05 sec)

mysql> SELECT * FROM Foo WHERE name = 'BAR';
+------+
| name |
+------+
| bar  |
+------+
1 row in set (0.12 sec)

mysql> SELECT * FROM Foo WHERE name = 'bAr';
+------+
| name |
+------+
| bar  |
+------+
1 row in set (0.05 sec)

好吧,既然问题是断断续续的,我就加入到“有趣”中来

Go(又名Issue9)使用大写的可见性:

如果你用大写字母命名某个东西,它就会被公众访问。 如果你使用小写,它将被包保护:

包装外可见:

func Print(v ...) { 
}

包外不可见

func print( v ... ) {
}

你可以在这个原始答案中找到更多。

foo是什么数据类型?

SELECT TOP 1
   NULL AS foo
INTO
   dbo.bar
FROM
   sys.columns --trivial

为什么所有东西都归零?

SELECT CAST('' AS int), CAST('' AS datetime), CAST('' AS float)

...除了这

SELECT CAST('' AS decimal)

Java的Integer类的基转换静态方法。P似乎很少有语言内置了这个功能。

很简单,Erlang有很多。例如,标点符号的三种形式,

a_function(SomeVariable) ->
  statements_end_with_commas(),
  case PatternMatching of
    0 -> now_we_end_with_semicolon;
    true -> except_the_last_one
  end.

%%  Function definitions end with periods!