在你看来,你遇到过的最令人惊讶、最怪异、最奇怪或最“WTF”的语言特性是什么?
请每个回答只回答一个特征。
在你看来,你遇到过的最令人惊讶、最怪异、最奇怪或最“WTF”的语言特性是什么?
请每个回答只回答一个特征。
当前回答
更多的是平台特性而不是语言特性:在iPhone上,创建一个无限循环,里面有一些计算,然后运行你的程序。你的手机会发热,当外面冷的时候,你可以把它当手暖。
其他回答
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)
在Perl中,可以通过修改一个类的@ISA数组来改变它的继承链,这让我很惊讶。
package Employee;
our @ISA = qw(Person);
# somwhere far far away in a package long ago
@Employee::ISA = qw(Shape);
# Now all Employee objects no longer inherit from 'Person' but from 'Shape'
回想起来,FORTRAN的计算goto是相当奇怪的。维基百科告诉我一些基础知识胜过它。
另一个著名的最爱是Algol 60的名称参数调用传递。
PHP对字符串中数值的处理。详见之前对另一个问题的回答,但简而言之:
"01a4" != "001a4"
如果你有两个包含不同数量字符的字符串,它们不能被认为是相等的。前导零很重要,因为它们是字符串而不是数字。
"01e4" == "001e4"
PHP doesn’t like strings. It’s looking for any excuse it can find to treat your values as numbers. Change the hexadecimal characters in those strings slightly and suddenly PHP decides that these aren’t strings any more, they are numbers in scientific notation (PHP doesn’t care that you used quotes) and they are equivalent because leading zeros are ignored for numbers. To reinforce this point you will find that PHP also evaluates "01e4" == "10000" as true because these are numbers with equivalent values. This is documented behaviour, it’s just not very sensible.
在C语言中,数组可以像这样被索引:
a[10]
这很常见。
然而,鲜为人知的形式(真正有效!)是:
10[a]
这与上面的意思相同。