【问题标题】:Swift - How to check if var is nil?Swift - 如何检查 var 是否为零?
【发布时间】:2016-06-20 11:16:33
【问题描述】:

我需要检查 dataArray 中的最后一个元素是否为 nil,所以我正在运行以下代码:

 if(dataArray.last == nil){
     print("dataArray.last == nil");
 } else {
     print("dataArray.last != nil , last = " + String(dataArray.last));
 }

奇怪的是它正在打印这个:

dataArray.last != nil , last = Optional(nil)

这是说尽管没有满足 if 条件,但最后一个元素是 nil。这怎么可能?

另外,如果我打印String(dataArray),这就是返回的内容:

[itemData,itemData , itemData , nil ,  nil , nil].

【问题讨论】:

标签: ios swift swift2 ios9


【解决方案1】:

firstlast 数组方法返回可选值,包含 nil 或数组元素。展望未来,数组元素本身可以为零。让我举个简单的例子:

let dataArray: [String?] = ["a", nil]
let lastElement = dataArray.last

您认为lastElement 具有String? 类型,但它却具有String?? 类型。当您检查dataArray.last 是否为零时,您只需确认该数组不为空。我建议您使用可选绑定:

if let lastElement = dataArray.last, _ = lastElement{         
    print("dataArray.last != nil , last = " + String(dataArray.last));        
}else{
    print("dataArray is empty OR last element of dataArray is nil");
}

【讨论】:

  • 您解释了问题发生的原因,但您的代码与问题中的代码相同,并产生相同的输出。
  • @MartinR 你是对的,谢谢你的指点。答案更正
  • 您使用if let 有条件地将dataArray.last 分配给lastElement,但是在if 语句正文中您使用dataArray.last 而不是lastElement,因此完全违背了目的if if let 声明
  • @AMomchilov 在问题的上下文中你不应该关心它。我特地对代码做了最小的改动:我让 unnamed var _ 和 unwrapped dataArray.last,这将输出关于 doubled Optional 类型的视觉信息。
【解决方案2】:

正如其他答案中所解释的,last 属性 Element 的集合具有 Element? 类型,并返回 nil 如果集合为空。在您的情况下,元素类型本身是 一个可选类型Item?,所以可能有三种情况:

  1. 数组为空:dataArray.lastnil aka .None
  2. 数组不为空,最后一个元素为nildataArray.last.Some(nil)
  3. 数组不为空,且最后一个元素不是nildataArray.last.Some(.Some(element)

如果你想区分这三种情况,你必须打开 两次:

let dataArray: [String?] = [ "a", "b", "c", nil ] // As an example

if let lastElement = dataArray.last {
    if let lastUnwrapped = lastElement {
        print("Last element is", lastUnwrapped)
    } else {
        print("Last element is nil")
    }
} else {
    print("Array is empty")
}

这可以用开关和可选模式短接:

switch dataArray.last {
case let element??:
    print("Last element is", element)
case let element?:
    print("Last element is nil")
case nil:
    print("Array is empty")
}

如果你只对数组的最后一个元素不是nil感兴趣, 那么您可以将if case 与可选模式一起使用:

if case let element?? = dataArray.last {
    print("Last element is", element)
} else {
    print("Last element is nil, or array is empty")
}

这里element??.Some(.Some(element)) 的快捷方式,它 匹配案例 #3。


如果你想为数组重新实现last 方法,那么它 只是

extension Array {
    func lastMe() -> Element? {
        if isEmpty {
            return nil
        } else {
            return self[count - 1]
        }
    }
}

如果元素类型是可选的Item?,则返回类型 变为Item??

【讨论】:

  • 感谢您的回答,但我只是想让您知道我声明了 dataArray: [itemData!] 。这与 dataArray: [itemData?] 有什么不同
  • martin !,非常感谢你,这很有帮助,但你能告诉我最后一个函数是如何实现的吗?我只想知道如何返回 optiona(nil) 。谢谢
  • @david:我已经修复了最后一个方法(在 vacawama 的评论之后),现在这三个方法都可以使用隐式展开的选项。
  • @vacawama & Martin 再次感谢。但是你能告诉我最后一个功能是如何实现的吗?我的意思是:我需要创建一个接受数组并最后返回的函数。只是为了了解 last 是如何工作的
  • @david:如果数组为空,该函数应该返回什么?或者如果最后一个元素为零?
【解决方案3】:

你为什么会得到这个结果?

让我们看看这段代码

let dataArray: [Int?] = [1, nil]

if let last = dataArray.last {
    print(last)
}

打印出来

nil

它确实发生了,因为 dataArray 被定义为可选的Int(又名Int?)的数组。所以last 属性确实返回一个包含nilOptional 值。

所以if 子句得到满足,if 的主体被执行。

这是正确的语法

let dataArray: [Int?] = [1, nil ,3]

if let lastOptional = dataArray.last, last = lastOptional {
    print("dataArray.last != nil, last = \(last)")
} else {
    print("dataArray.last == nil")
}

输出:

dataArray.last != nil, last = 3

说明

让我们看看if。它由 2 个子句组成,必须满足两个子句才能将 if 解析为 true

#1 子句

let lastOptional = dataArray.last

如果最后一个元素确实存在,则成功。它将是一个Int?,因此是一个包含nilInt 的可选值。在这两种情况下,该条款都得到满足。

当数组NOT为空时,基本上第一个子句就满足了。

#2 子句

last = lastOptional

如果可选的最后一个 (Int?) 元素成功解包,则成功。

当最后一个元素确实存在并且不是包含 nil 的 Optional 时,满足该子句。

总结

if 的主体内,您可以使用last,您可以确定它是展开后的值。事实上 last 的类型是Int

【讨论】:

  • 您的示例不是可选数组(如问题所示)。
【解决方案4】:

试试这个

if let lastObject = dataArray.last{

            print("dataArray.last != nil", + String(lastObject));
        }else{

            print("dataArray.last == nil );
        }

【讨论】:

  • “试试这个”没有任何解释的答案并没有真正的帮助。
  • 可能是因为语法一般是if let _ = ... 而不是if var,这种情况下可能也可以使用guard语句。
  • @MartinR 我写了这个答案,因为如果它有效,我会向他解释它为什么会发生以及它的正确答案。请不要在没有任何真实理由的情况下投反对票。
  • @AhmadIshfaq:我试图解释你这不是一个好的答案,但我还没有投票(还)。 – 不要假设没有任何真实理由的任何投票!
【解决方案5】:

数组有可选功能

最后

Optional(nil) 不等于 nil

如果你打印出 dataArray.last 然后 Optional(nil) 将被打印

试试这个

if let _ = dataArray.last {
     print("dataArray.last != nil , last = " + String(dataArray.last));
}else{
     print("dataArray.last == nil");
}

【讨论】:

  • 我的回答是第一个,对不起 =)
  • 你是对的!第二种方法已正确编辑谢谢:)
  • @SwiftyCruz:如果数组为空,你的第一个代码会崩溃。
  • @appzYourLife 编写的第一个代码与作者的代码相比变化最小,第二个是准确的 :)
  • @SwiftyCruz:但你确实写了try this,它确实编译。请修正你的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 2014-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多