为什么 1...1 的计算结果为 10.1?

Why does 1...1 evaluate to 10.1?

我刚遇到来自 3v4l 的 PHP 片段:https://3v4l.org/jmrZB

echo 1...1; //10.1

恐怕我不知道如何解释它的结果。为什么这被认为是有效的?

因为它被解释为 1. . .110.1)所以你得到 10.1

点(.)在PHP中有两个作用:

  1. 作为十进制数字,当它是实数的一部分时,例如1.1。整数部分和小数部分在实数上都是可选的,但在同一时间。这意味着 1..1 都是 PHP 中的有效实数,但 . 不是数字。
  2. 作为 string concatenation operator。此运算符将两个字符串子表达式连接成一个更大的表达式。较大表达式的值是子表达式的字符串值的串联。不是字符串的子表达式在连接之前转换为字符串。
    例如。 1 . 1'1' . '1' 相同,其值为字符串 '11'.

表达式 1...1 被解析为 1. . .1。根据上面所说,1..1是实数(1.00.1),中间的点(.)是字符串连接运算符。

将数字转换为字符串时,PHP 使用此操作所需的最少字符数。如果实数只有整数部分,则表示该数为整数,没有小数点和小数。

这就是为什么 1. . .1'1' . '0.1' 相同并且表达式的最终值为 10.1.

为什么 1...1 是这样解析的?

解析器从左到右读取表达式。 1 告诉它一个数字从那里开始。 1. 是一个有效的实数,但 1.. 不是。它将 1. 保留为数字,然后下一个点是连接运算符。下一个 . 后面跟着一个数字,是另一个实数 (.1) 的开头。

总而言之,1...11. . .1一样。

戴上大括号就清楚了:

(1.) . (.1)

  • 1. 被解释为 1
  • . 是字符串 concatenation
  • .1 被解释为 0.1

这全部放到一个字符串中就是10.1 作为一个字符串.

var_dump(1...1) 产量string(4) "10.1"

不同的操作。

1. <?php echo 1.1; ?> // gives simple 1.1
2. <?php echo 1...1; ?> // gives 10.1
3. <?php echo 1..'1'; ?> // gives 11
4. <?php var_dump(1.); ?> // gives 1
5. <?php var_dump(.1); ?> // gives 0.1

现在,我们的奇葩操作

echo 1...1 

被视为 4 号和 5 号的串联,得到 10.1