Swift 敏捷的从Int中获取Int的最佳方法?

Swift 敏捷的从Int中获取Int的最佳方法?,swift,optional,Swift,Optional,我刚开始学习Swift,但我仍然对选项感到困惑。我想知道,最好的方法是什么,或者我应该遵循什么方法 let arrayOptional : [Int?] = [25, 30, nil, 50, nil] // Optional Binding var sum = 0 for i in arrayOptional { if let temp = i { sum += temp } } sum = 0 // Forced Unwrapping for i in ar

我刚开始学习Swift,但我仍然对选项感到困惑。我想知道,最好的方法是什么,或者我应该遵循什么方法

let arrayOptional : [Int?] = [25, 30, nil, 50, nil]
// Optional Binding
var sum = 0
for i in arrayOptional {
    if let temp = i {
        sum += temp
    }
}
sum = 0

// Forced Unwrapping
for i in arrayOptional {
    if i != nil {
        sum += i!
    }
}
sum = 0

// ?? operator
for i in arrayOptional {
    sum += i ?? 0
}

那么,使用一种方法比使用另一种方法有什么好处呢?

您可以使用
打开它,如果让
保护。。。else

//If let would be optimal for your example because you are not doing much after unwrapping 
for i in arrayOptional {
    if let temp = i {
        sum += temp
    }
}

// guard...else would be useful when you have a lot to do and you don't want to keep on nesting code inside {}
for i in arrayOptional {
    guard let temp = i else {
        continue
    }
    sum += temp
}
强制展开(
)仅在您希望应用程序崩溃或确定可选应用程序不包含
nil
时执行。例如:将单元格、UITextfield和UITextView的
text
属性出列是可选的,但决不会是
nil


nil合并运算符(
)提供了一个默认值,以防可选值变为
nil
。将可选变量分配给非可选变量时使用它。

您可以简单地使用
reduce
来获得总和

let sum = arrayOptional.reduce(into: 0, {$0 += $1 ?? 0})
通常,您应该使用可选绑定(您的第一种方法)或nil合并操作符(您的最后一种方法)来安全地展开选项,nil检查然后强制展开不是推荐的方法

如果您想坚持使用循环方法,可以在循环变量声明中使用模式匹配使其更简单(循环体将仅对
arrayOptional
中的非nil值执行):


您所能做的就是使用
compactMap
函数,因此您将从
arrayOptional
中获取非零值,然后使用
reduce
函数来获得结果

sum = arrayOptional.compactMap{ $0 }.reduce(0, +)

尽可能避免强制展开,其他两种方法中的哪一种最好取决于情况和个人品味,在您的具体示例中,我会使用最后一种方法,但通常我更喜欢使用第一种方法。另一种方法:
for case let I?在arrayOptional{sum+=i}
中,无需在数组上迭代两次,正如我的答案所示,可以使用一个
reduce
。@DávidPásztor您是对的,但这比您的解决方案更容易理解。但是,它可能应该包括
.lazy
,以避免创建不必要的数组。+1(是的;
.lazy
可能应该添加,但这对理解并不重要)。这绝对是Swift的正确方式。对于@JoakimDanielson,我知道问题是让绑定、强制展开还是零合并更好。正确答案是“以上都不是;使用一个高阶函数来实现你的意思。”删除选项。总和完美。@DávidPásztor
reduce
方法很简洁,但是加法将对所有元素执行,无论它们是否为
nil
@Carpsen90是,但它不会影响结果,因为默认值是使用nil合并运算符设置为
0
。@DávidPásztor是,它不会,我的意思是从效率的角度perspective@Carpsen90一次加法在计算上并不昂贵,所以我不必担心:)
sum = arrayOptional.compactMap{ $0 }.reduce(0, +)