把赋值运算符写在 if 判断里好吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Jat001
V2EX    PH

把赋值运算符写在 if 判断里好吗?

  •  1
     
  •   Jat001 2014 年 5 月 17 日 6683 次点击
    这是一个创建于 4361 天前的主题,其中的信息可能已经有所发展或是发生改变。
    太容易跟比较运算符搞混了,对 php 新手也不友好。

    嗯,还是 @explon 一下吧~
    第 1 条附言    2014 年 5 月 17 日
    大部分人都这样写
    $a = 'foo';
    if ($a) {
    echo 'bar';
    }
    可有人却这样写
    if ($a = 'foo') {
    echo 'bar';
    }
    虽然两种写法结果一样,但第二种很容易把赋值运算看成比较运算。
    30 条回复    2014-05-21 15:53:00 +08:00
    bearcat001
        1
    bearcat001  
       2014 年 5 月 17 日
    C里为了避免把判断写成赋值,一般这样做
    if (3 == a)
    bearcat001
        2
    bearcat001  
       2014 年 5 月 17 日   1
    没写完就提交了...
    编译器会报错的,PHP也一样
    所以赋值用 $a = 3 ,判断反过来写 3 == $a
    for4
        3
    for4  
       2014 年 5 月 17 日
    这个要看是什么语言。
    大部分语言是不建议这样写的。
    for4
        4
    for4  
       2014 年 5 月 17 日
    没看到TAG ,
    PHP里面 不要这样写
    ashitaka
        5
    ashitaka  
       2014 年 5 月 17 日
    第一种方法比较好 意图很明显 判断$a 的值是否为空
    第二种意图混乱 你到底是判读$a 的值是否为空 还是$a的值是否为'foo'
    虽然此处按 lz 的意思是前者
    但是当代码给别的人看时 就要通过判断来推测原作者意图了
    raincious
        6
    raincious  
       2014 年 5 月 17 日
    看习惯。两种代码没有区别,只是节省了行数。属于小Trick类型的语法。

    个人倾向于如果$a接受的是函数返回值,那么无所谓了。但是如果接受的是变量set,那么上面的语法是没有意义的。

    $a = 'foo'必然不是false,所以if里面的语法必然会被执行。所以简直不如就是

    $a = 'foo';
    echo $a;
    Jat001
        7
    Jat001  
    OP
       2014 年 5 月 17 日
    @raincious 上面的列子可能太简单了,再举一个:
    if ($a = trim($_GET['foo']))
    $a 接受的确实是函数返回值。
    Wy4q3489O1z996QO
        8
    Wy4q3489O1z996QO  
       2014 年 5 月 17 日
    @Jat001 一般后面需要用到$a 才这样写,即完成判断,又完成赋值。
    yukirock
        9
    yukirock  
       2014 年 5 月 17 日
    既然是 $a 值字符串常量,那什又要做一次 if 判呢?
    的代是不是重可能更好?
    zythum
        10
    zythum  
       2014 年 5 月 17 日
    @yukirock 她只是举个例子

    如果这样的例子是不是更好

    if ($param = $_GET['param']) {
    //then use $param here.
    }
    jsonline
        11
    jsonline  
       2014 年 5 月 17 日 via Android
    等你哪天遇到坑了就知道了。
    jsonline
        12
    jsonline  
       2014 年 5 月 17 日 via Android
    写代码最好的习惯是,每一行都 donot make me think.
    raincious
        13
    raincious  
       2014 年 5 月 17 日   1
    @yukirock

    对编译器来说基本山是一回事。但是多了一行,很多人感觉不爽,包括我。

    @Jat001

    还是看规范的问题。PHP的PSR2没有规定这样的内容,可以理解为它把这个交给了程序员自行组织。

    如果你能制定规则的话,那么可以指定一个规则来约束程序员的写法。如果不能的话,可以这样改变自己的思维来适应:

    你想要检查$_GET['foo']这个里面的值是不是设定,包括是空白,那么原先的写法事实上是

    if (trim($_GET['foo'])) { // 外部变量请自行isset
    $a = $_GET['foo'];
    // TODO
    }

    然后你发现,这样浪费了一行,自然要想办法修改,那么就顺理成章的改成了
    if ($a = trim($_GET['foo'])) {
    // TODO: Use $a
    }

    个人感觉可读性差别不大,而且个人也没有因为这个出错。可能只是对待刚刚入门的新人时应该注意下。
    messense
        14
    messense  
       2014 年 5 月 17 日
    最近看 APUE 里面其实很多赋值语句写在 if 里,不过一般是这样的:

    int fd;
    if ((fd = open("/dev/null", O_RDWR)) < 0) {
    fprintf(stderr, "open error");
    exit(1);
    }
    raincious
        15
    raincious  
       2014 年 5 月 17 日
    @raincious 哦,说错了:

    - 你想要检查$_GET['foo']这个里面的值是不是设定,包括是空白,那么原先的写法事实上是
    + 你想要检查$_GET['foo']这个里面的值是不是非空,包括是空白,那么原先的写法事实上是
    nicai000
        16
    nicai000  
       2014 年 5 月 17 日
    极其讨厌楼主和一楼的写法
    hhkbp2
        17
    hhkbp2  
       2014 年 5 月 17 日
    不是太好,不过go...
    Jat001
        18
    Jat001  
    OP
       2014 年 5 月 17 日
    @raincious 我一般这样写
    $a = trim($_GET['foo']);
    if ($a) {
    //do some thing
    }
    可公司的代码基本是这样写的
    if ($a = trim($_GET['foo'])) {
    //do some thing
    }
    因为我有强迫症,所以要发个帖子问问……

    另外我也写 shell 脚本,在 shell 中,一个等号与两个等号是一样的,都是比较运算符。
    explon
        19
    explon  
       2014 年 5 月 17 日
    你的举例不对,公司大部分逻辑是这样子的,基本赋值的是一个数组,存在下面执行循环

    if ($inbox_dialog = $this->model('message')->get_inbox_message($_GET['page'], get_setting('contents_per_page'), $this->user_id))
    {

    foreach ($inbox_dialog as $key => $val)
    {
    explon
        20
    explon  
       2014 年 5 月 17 日
    @Jat001 90% 以上 if 赋值都是 model 返回来一个数组,没有你举例的那种情况存在
    alsotang
        21
    alsotang  
       2014 年 5 月 17 日
    不是好习惯
    Jat001
        22
    Jat001  
    OP
       2014 年 5 月 17 日
    @explon 就是举个列子,都是把赋值和判断写一块,看着不舒服。
    explon
        23
    explon  
       2014 年 5 月 17 日
    @Jat001 你的例子赋值都是 100% 为真,而 model 有时候是返回 false,完全曲解了意思,公司的代码 if 赋值逻辑很清晰是 14 楼 @messense 那种逻辑,这在开源产品中很常见,按照你的描述的写法完全是多写一行。
    superbear
        24
    superbear  
       2014 年 5 月 17 日
    @jsonline 利人利己
    Jat001
        25
    Jat001  
    OP
       2014 年 5 月 17 日
    @explon 就举了俩个简单的例子,方便理解。
    第一个例子可能举的确实不好,但在第二例子中
    $_GET['foo'] 有可能是空格,tab,换行符等,所以 $a = trim($_GET['foo']) 返回的可能是 false。

    但我想问的是,把赋值和判断写一块好不好?是否易于理解,是否容易出错,对新手是否友好等?
    explon
        26
    explon  
       2014 年 5 月 17 日 via iPhone
    @Jat001 我们程序不会像你举例这样写,if 中赋值的情况只有在对函数处理后返回判断变量是否有数据(非字符串处理),是则下面要对数据进行二次处理的情况下出现,你的理解错了。

    准确的说我们程序的代码风格很大是受了国外一款著名商业论坛程序 vBulletin 3 的影响,你有兴趣可以下一个看一看
    freefcw
        27
    freefcw  
       2014 年 5 月 17 日
    @Jat001 个人有一个原则,代码含义尽量唯一性,不出现第二个意思,方便自己也方便别人
    Jat001
        28
    Jat001  
    OP
       2014 年 5 月 17 日
    @explon 我就是吐槽这种代码风格,特别是再加个 ! 取反的时候,看着就更蛋疼了。
    nekop
        29
    nekop  
       2014 年 5 月 18 日
    Objective-C程序员表示OK!
    solu
        30
    solu  
       2014 年 5 月 21 日
    突然想到zephir有fetch这么一个操作符
    http://zephir-lang.com/operators.html#fetch
    额!!跑题了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2670 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 71ms UTC 07:20 PVG 15:20 LAX 00:20 JFK 03:20
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86