【问题标题】:Unwrapping an optional in Swift 4在 Swift 4 中解开一个可选项
【发布时间】:2018-09-04 13:16:08
【问题描述】:

我在操场上有以下代码:

// Create an empty array of optional integers
var someOptionalInts = [Int?]()

// Create a function squaredSums3 with one argument, i.e. an Array of optional Ints
func squaredSums3(_ someOptionalInts: Int?...)->Int {
    // Create a variable to store the result
    var result = 0

    // Get both the index and the value (at the index) by enumerating through each element in the someOptionalInts array
    for (index, element) in someOptionalInts.enumerated() {
        // If the index of the array modulo 2 is not equal to 0, then square the element at that index and add to result
        if index % 2 != 0 {
            result += element * element
        }
    }

    // Return the result
    return result
}

// Test the code
squaredSums3(1,2,3,nil)

行结果 += element * element 给出以下错误“可选类型'Int的值?'没有打开;你是不是要使用“!”或者 '?'?”我不想使用“!”我必须测试 nil 的情况。我不确定在哪里(甚至如何说实话)打开可选的。有什么建议吗?

【问题讨论】:

  • 做一个if let:if let unwrappedElement = element { if index %2... {} }?这是基本的展开。或者你可以解开已经 someOptionalInts 而不是 someOptionalInts,而是使用 let unwrappedSomeInts = someOptionalInts.flatMap{ $0 } 并将其用于循环。
  • result = (element ?? 0) * (element ?? 0)

标签: swift optional swift-playground optional-values


【解决方案1】:

你所要做的就是打开可选的:

if let element = element, index % 2 != 0 {
    result += element * element
}

这将忽略 nil 值。

与任何类型的映射相比,它的优势在于您不必额外遍历数组。

【讨论】:

  • 好的,谢谢!我是可选的新手,它们只是有点令人困惑。我敢肯定,当我更多地使用它们时,我会习惯它们。谢谢!
  • 完全没问题。他们肯定需要一些时间来适应。
  • @MatthewSpir​​e 但你说你不能忽略那些为零的!在这里你也可以这样做。
  • @LinusGeffarth 我认为他的意思是他不能只过滤掉它们,因为那样会丢弃索引。一个compact map会把[1, nil, 2, 3]变成[1, 2, 3],然后他对index的mod操作就会出错。
  • 啊,可能是的。
【解决方案2】:

如果你想从数组中省略 nil 值,你可以压缩映射它:

for (index, element) in (someOptionalInts.compactMap { $0 }).enumerated() {

那么,element 将不再是可选的。


如果您想将所有 nil 值视为 0,那么您可以这样做:

if index % 2 != 0 {
    result += (element ?? 0) * (element ?? 0)
}

【讨论】:

  • 我不能忽略数组中的 nil 值。 squaredSums3(1,2,3,nil) 应该返回 4,这意味着它考虑了 nil 在数组中的事实,基本上只是忽略它。
  • @MatthewSpir​​e 那么你的目标是什么?你想如何处理 nil 值?是否应该像 0 一样对待它?
【解决方案3】:

出现错误是因为您必须指定在元素为 nil 时要执行的操作

if index % 2 != 0 {
    if let element = element {
        result += element * element
    }
    else {
        // do whatever you want
    }
}

【讨论】:

  • 不,如果元素为零,他们不必指定要做什么。他们所要做的就是打开它。
【解决方案4】:

我会这样写:

for (index, element) in someOptionalInts.enumerated() {
    guard let element = element, index % 2 == 0 else { continue }
    result += element * element
}
// result == 10

guard 语句意味着我只对element 不是nil 感兴趣并且 它的index 是偶数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多