奇怪的行为三元运算符

Pie*_*pje 2 php

来自C#我必须用PHP做一个项目.

我正在使用此代码:

$transport = 'T';

$vehicle = (
 ( $transport == 'B' ) ? 'bus' :
 ( $transport == 'A' ) ? 'airplane' :
 ( $transport == 'T' ) ? 'train' :
 ( $transport == 'C' ) ? 'car' :
 ( $transport == 'H' ) ? 'horse' :
 'feet' );

echo $vehicle;
Run Code Online (Sandbox Code Playgroud)

我希望它可以打印train,但我明白了horse.键盘示例:http://codepad.org/rWllfrht

谁能解释这种奇怪的行为?

mea*_*gar 16

没有看到任何解释为什么你的代码在其他答案中被破坏,所以这里是一个快速的破败.

这里的问题更明显的是你添加括号以使隐含的评估顺序更加明确.

这是您的代码的精简版本,仍然会产生错误的"马"结果:

 $t = 'T';

 ( $t == 'T' ) ? 'train' : 
 ( $t == 'C' ) ? 'car' : 
 ( $t == 'H' ) ? 'horse' : 'feet';
Run Code Online (Sandbox Code Playgroud)

首先,让我们展开它:

( $t == 'T' ) ? 'train' : ( $t == 'C' ) ? 'car' : ( $t == 'H' ) ? 'horse' : 'feet'; 
Run Code Online (Sandbox Code Playgroud)

接下来,我将添加显式括号,其中已经存在隐含的括号:

((($t == 'T') ? 'train' : ($t == 'C')) ? 'car' : ($t == 'H')) ? 'horse' : 'feet';
Run Code Online (Sandbox Code Playgroud)

接下来,我们可以解决您的比较:

((true ? 'train' : false) ? 'car' : false) ? 'horse' : 'feet';
Run Code Online (Sandbox Code Playgroud)

你应该开始明白为什么会这样.第一个三元评估true ? 'train' : 'false''train':

('train' ? 'car' : false) ? 'horse' : 'feet';
Run Code Online (Sandbox Code Playgroud)

因为'train'当转换为布尔值时为true,结果现在是'car':

'car' ? 'horse' : 'feet';
Run Code Online (Sandbox Code Playgroud)

同样,因为非空字符串是"true",结果现在是"马".因此,第一次true出现在可怕的嵌套case语句中时,结果将级联所有剩余的语句,抛出下一个运算符的"true"分支的先前值.

解决方案是避免使用此代码.这是一个远远过于聪明的尝试,结果是一个破碎,难以理解的混乱.绝对没有理由使用它.选择一个switch声明,它的目的是为了你正在尝试做的事情.

  • 任何合理的语言都可以正常工作([Java](http://ideone.com/dde4pt),[C#](http://ideone.com/QF62Bh),[C++](http://ideone.com/Z2b8lJ )).记录的错误不是功能. (3认同)
  • 它在任何语言中都令人困惑,而且任何语言都会提供更好的结构,以明确的方式实现这一目标. (2认同)