为什么我的 Swift 三元运算符不起作用?

时间:2021-03-15 14:55:05

标签: swift loops conditional-operator

我正在学习 Swift 的第二天,我对三元运算符有以下疑问。

我有以下代码:

var list = [2, 4, 3, 6, 1, 9]

var sumOfEven = 0
var productOfOdd = 1

for item in list {
  item % 2 == 0 ? sumOfEven += item : productOfOdd *= item
}

这是不言自明的,但为了避免任何疑问,程序应该将 Int 数组中的所有偶数相加,然后将所有奇数相乘。

但是,当我运行上面的代码时,我有以下代码:

error: result values in '? :' expression have mismatching types '()' and 'Int'
  (item % 2 == 0) ? sumOfEven += item : productOfOdd *= item

我怎么会有不匹配的类型?!我已经尝试将 sumOfEvenproductOfOdd 声明为 IntDouble 但仍然不起作用...

如果我将 If...Else 替换为:

,一切正常
for item in list {
  if item % 2 == 0 {
    sumOfEven += item
  } else {
    productOfOdd *= item
  }

3 个答案:

答案 0 :(得分:2)

编译器需要一点帮助,由于在语言中实现运算符优先级的方式,三元组中的空格导致它变得混乱。如果您将语句括在括号中,那么它将编译并执行您期望的操作。

还有一个属性可以让你检查某个东西是否是(:)的倍数,它可以使代码更容易阅读,但如果你愿意,你可以使用 item % 2 == 0 并且它仍然可以工作。

var list = [2, 4, 3, 6, 1, 9]

var sumOfEven = 0
var productOfOdd = 1

for item in list {
    item.isMultiple(of: 2) ? (sumOfEven += item) : (productOfOdd *= item)
}

print(sumOfEven)     // 12
print(productOfOdd)  // 27

然而,三元组会使代码更难理解。这最好写成 if-else,就像您在问题中写的那样。

for item in list {
    if item % 2 == 0 {  // you could use item.isMultiple(of: 2) 
        sumOfEven += item
    } else {
        productOfOdd *= item
    }
}

答案 1 :(得分:1)

通常认为可以使用三元运算符仅当不涉及副作用,例如变异或打印。如果它只是将表达式的值计算为 A 或 B,那么您没问题。你可以这样做:

let list = [2, 4, 3, 6, 1, 9]
let (sumsOfEven, productOfOdd) = list.reduce((0, 1)) { (result, item) in
item.isMultiple(of: 2) ?
    (result.0 + item, result.1) : (result.0, result.1 * item)
}

答案 2 :(得分:0)

我会说每次你去使用三元运算符时,停下来问问自己,它是否让代码更容易遵循和维护?从答案是否定的假设开始,并且仅在确实提高可读性的情况下才使用它。

我要避免的一件事是在您给出的示例中具有副作用的情况(如果表达式为真,它会添加到 sumOfEvent,如果它为假,它将 productOfOdd 乘以某个值。)

相反,在这样的情况下使用它:

var useFirst = true

var firstAddend = 1
var secondAddend = 2

let aValue += useFirst ? firstAddend : secondAddend

但前提是它使代码更清晰、更易于维护。

这比:

if useFirst {
    addValue += firstAddend
} else {
    addValue += secondAddend
}

(不是真的,不是。)


编辑

在上面的示例中,三元运算符版本的一个参数是 DRY(不要重复自己)原则。在 if/else 版本中,变量 addValue 出现了两次。如果在将来的某个日期更改该变量,则必须记住在两个地方都更改它,否则有引入错误的风险。我个人认为在这种情况下可读性更重要,并且发现 if/else 版本更容易阅读。 (而且我一直在使用类似 C 的语言进行编程,其中包括专业的三元运算符。 ≈ 35 年。)