Segmentfault原文地址:关于php中的switch语句 报错
说真的,他这段代码,写的真的,不咋地……
当然我不是来写文章批判他的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
switch($rank) { case 1: $speed = 50; break; case 2: $speed = 48; break; /*…… 中略 ……*/ case 9: $speed = 37; break; case 10: $speed = 36; break; case 21 > '$rand' >10: $speed = 35; break; case 31 > '$rand' > 20: $speed = 34; break; /*…… 中略 ……*/ case 401 > '$rand' > 300: $speed = 27; break; case 501 > '$rand' > 400: $speed = 26; break; } //在运行的时候报错>符号有误 这是什么情况啊 |
分析
这段代码……问题很多,只好一一道来。
阶段一:
首先’$rand’是一个字符串变量,他的值就是字符串’$rand’,布尔值是true。这个判断条件写错了吧。
我猜是想写前面的$rank
之后条件这里要使用&&连起来,因为没有结合的相同优先级的运算符不能连在一起使用。
php手册:运算符优先级
所以其实应该写成 10 >= $rank && $rank >2
而且如果连续写的话,每个阶段加上括号,就成了 case (10 >= $rank) > 2,如果 $rank = 5,那就变成布尔值 true > 2。
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php if (true > 2) { echo "WTF"; } else { echo "WTH"; } if (true == 2) { echo "WTF"; } else { echo "WTH"; } |
觉得结果会是什么?
这个也是有相关文档的:比较运算符
阶段二:
来看我简写后的这段代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
echo getSpeedByRank(1); echo ','; echo getSpeedByRank(5); echo ','; echo getSpeedByRank(11); echo ','; echo getSpeedByRank(100); echo '.'; function getSpeedByRank($rank = 1) { switch($rank) { case 1: $speed = 1;//(匹配结果A) break; case 2: $speed = 2;//(匹配结果B) break; case 10 >= $rank && $rank >2: $speed = 5;//(匹配结果C) break; case 20 >= $rank && $rank > 10: $speed = 15;//(匹配结果D) break; default: $speed = 20;//(匹配结果E) } return $speed; } |
这个运行结果是 1,5,15,20. ,可以认为$rank匹配了结果ACDE。
那么如果我令$rank = 0,按照上面的猜想,是不是应该匹配到default,即结果E,speed等于20呢?
你可以运行以下,很可惜speed = 5,匹配了C。
为什么会符合 $rank = 0 时,会 switch 到 case 10 >= $rank && $rank >2?
阶段三
改写上面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
echo getSpeedByRankAsIf(1); echo ','; echo getSpeedByRankAsIf(5); echo ','; echo getSpeedByRankAsIf(11); echo ','; echo getSpeedByRankAsIf(100); echo ','; echo getSpeedByRankAsIf(0); echo '.'; function getSpeedByRankAsIf($rank = 1) { switch(true) { case $rank == 1: $speed = 1; break; case $rank == 2: $speed = 2; break; case 10 >= $rank && $rank >2: $speed = 5; break; case 20 >= $rank && $rank > 10: $speed = 15; break; default: $speed = 20; } return $speed; } |
结果是: 1,5,15,20,20.
阶段二中,$rank = 0时,会switch到case 10 >= $rank && $rank >2的理由,就是$rank = 0,$rank的布尔值是false;case条件 case 10 >= 0 && 0 > 2 为false,(false == false)就为true,所以会匹配到这个条件。
综上
你可以理解为,
1 2 3 4 5 6 7 8 9 10 |
switch($a) { case ($b): /*code_b*/ break; case ($c): /*code_c*/ break; default: /*code_default*/ } |
其实可以理解为:
1 2 3 4 5 6 7 |
if ($a == $b) { /*code_b*/ } elseif ($a == $c) { /*code_c*/ } else { /*code_default*/ } |
注意break的存在,如果没有break,那么这个if就更复杂了,会一直向下匹配到所有匹配条件,用if就难写了。
补充
注意最初的代码switch条件中,没有写default,那么当 $rank >=1 && $rank < 501 时还好,如果 $rank 在这个范围外时,会怎样呢?
批判
如果抛去原文提问者的变量书写错误,那么这还是一道比较值得讨论的问题的。
而且提问者称自己是写C++和JAVA的,我对这两种语言无爱,也不了解,所以我也不想去了解这种写法在这两种语言中是如何使用的。
虽然我的答案没有被采纳,但其实无所谓,那个被采纳的答案在我开始写答案的时候就存在了,而且说得也没错,我还给他投了赞成票。而我的答案在题主采纳时还没写完。
然而当我看到这个问题的时候,下面的答案其实多数都是这样的:
case后怎么还有比较运算符啊
你这是哪里学来的用法,谁教过你case里能这么写了?
曾经有人说我戾气太重,然而当你身处在一个如此低底线的环境中时,除了发怒,否则就只能 人善被人欺,马善被人骑。
很多中文社区都有这种问题,segmentfault上的几个分数高的用户,他们的回答往往都是这种。
多数人在这种互助社区的目的并不是帮助或者学习,而是虚荣和刷存在感。这个现象最明显的就是百度知道,以及各种所谓的QQ技术群了。
回复量很多,然而多数都是垃圾内容,这就是目前中文社区的环境了。
所以个人感觉,很多高手都是不使用这些中文社区的,也不使用QQ、微信或者其他可能会跟扯犊子染上关系的社交工具。
3 comments
穹庐
2016 年 9 月 7 日 在 下午 1:52 (UTC 8) Link to this comment
专门来看看你博客优化得怎么样了
石樱灯笼
2016 年 9 月 7 日 在 下午 2:04 (UTC 8) Link to this comment
没有优化,暂时没钱。用的仍然是之前的虚拟主机。
萃香西瓜
2016 年 9 月 7 日 在 下午 9:47 (UTC 8) Link to this comment
其实那个被采纳的答案也是错的,只有你的是正确的
switch其实可以看成是if else的一个语法糖,题主那个写法我觉得只用switch是不合理的
不过我也没写过php,不知道php会不会对这种情况再给switch加一个语法糖