代码之家  ›  专栏  ›  技术社区  ›  abelenky

条件运算符不是语句?

  •  22
  • abelenky  · 技术社区  · 14 年前

    我有一个简单的小代码片段让我很沮丧:

    HashSet<long> groupUIDs = new HashSet<long>();
    groupUIDs.Add(uid)? unique++ : dupes++;
    

    在编译时,它会生成错误:

    只有赋值、调用、增量、减量和新对象表达式才能用作语句

    HashSet.Add 被记录为返回bool,所以三元(?)操作员应该工作, 这看起来是一种完全合法的方法来跟踪我添加到散列集中的唯一和重复项的数量。

    当我将它重新格式化为if-then-else时,它工作得很好。

    有人能解释一下这个错误吗?如果有一种方法可以用简单的三元运算符来解释的话?

    9 回复  |  直到 12 年前
        1
  •  19
  •   sth Alien    14 年前

    根据错误消息,三元运算符不能用作语句。你需要这样做才能把它变成作业:

    int dummy = groupUIDs.Add(uid)? unique++ : dupes++;
    

    话虽如此,我还是建议用if-then-else。它不那么令人困惑,因为它不涉及“魔法”虚拟变量的创建…

        2
  •  16
  •   Eric Lippert    14 年前

    正如其他人指出的,条件运算符不是一个合法的语句表达式。(合法语句表达式包括赋值、调用、增量、递减和构造。)

    不过,这里也有一个文体问题。在我看来, 表达式应该对其值有用 声明应该对其副作用有用 . 你遇到的问题是你的表达式只对它的副作用有用,这是一个糟糕的代码味道。

    你有副作用,所以使用条件语句而不是条件表达式。

        3
  •  7
  •   Gabe    13 年前

    你没有把三元的值结果设置为任何原因。

    HashSet<long> groupUIDs = new HashSet<long>();
    int count = groupUIDs.Add(uid)? unique++ : dupes++;
    
        4
  •  5
  •   ANeves    14 年前

    三元运算符不是语句。因此,它不能单独在指令中使用-它相当于编写

    "something that is not a statement";
    

    为了说明这一点,您应该去掉三元运算符并使用if。

        5
  •  4
  •   Andrew Hare    14 年前

    编译器没有抱怨 Add 它抱怨你的条件表达式不是一个完整的语句。

    有些语言(如javascript)允许您使用条件表达式来分支逻辑,就像您在这里所做的那样,但是c要求您将条件表达式的结果赋给一个变量。一旦您分配了表达式的结果,您就完成了一个完整的语句,编译器很高兴。

        6
  •  2
  •   Brian Walker    14 年前

    你需要用三元运算符的值来做一些事情…

    HashSet<long> groupUIDs = new HashSet<long>();
    int newCount = groupUIDs.Add(uid)? unique++ : dupes++;
    

    或者-使用if

    HashSet<long> groupUIDs = new HashSet<long>();
    if (groupUIDs.Add(uid))
       unique++;
    else
       dupes++;
    
        7
  •  1
  •   Dan Tao    14 年前

    gmcalab和sr pt是对的;三元运算符是用来给你一个结果的,就像 1 + 1 给你 2 . 你不能只写:

    1+1 ;

    这里(我认为)的混乱之处在于,你把三元运算符当作一个函数来考虑。

        8
  •  1
  •   Andy Johnson    14 年前

    这个 description 语言引用中的三元运算符表示

    如果条件为true,则第一个表达式 被评估并成为结果; 如果为false,则第二个表达式是 评估并成为结果。

    虽然语言引用并没有明确说明,但看起来三元组只能在赋值的上下文中使用。你没有对结果做作业。

    在我看来,作为if/else的重写会更清楚。

        9
  •  0
  •   T. Stone    14 年前

    如果这是不可接受的,为什么你的线路是?只需使用if语句:-)

            bool b = false;
            b?callB():callA();