【问题标题】:Swift: optional array countSwift:可选数组计数
【发布时间】:2014-06-30 13:04:05
【问题描述】:

在 Objective-C 中,如果我有以下属性:

@property (strong, nonatomic) NSArray * myArray;

myArray 中返回多个对象的方法如下所示:

- (NSInteger) numberOfObjectsInMyArray
{
    return [self.myArray count];
}

这将返回数组中对象的数量,如果myArray == nil,则返回0;

我能想到的在 Swift 中执行此操作的最佳等价物是:

var myArray: Array<String>?

func numberOfObjectsInMyArray() -> Int
{
   return myArray ? myArray!.count : 0
}

因此检查可选数组是否包含一个值,如果是则解包数组并返回该值,否则返回 0。

这是正确的方法吗?还是有更简单的?

【问题讨论】:

  • 也许返回一个可选的Int?
  • 可选的Int不是必须的,因为这里每种情况都有一个值返回值。
  • return myArray?.count... 是的,肯定更短。但当然,这取决于在允许选项的地方使用的结果。例如func numberOfSectionsInTableView(tableView: UITableView!) -&gt; Int 不好
  • 为什么要为 nil 数组返回 0?一个空数组有 0 个元素。 nil 数组不存在。有根本区别。
  • @ashleyMills,我已经更新了我的答案:有任何理由拥有一个可选数组吗?

标签: arrays swift optional


【解决方案1】:

尝试使用nil coalescing operator

根据 Apple 文档:

nil 合并运算符 (a ?? b) 如果可选 a 包含值,则将其解包;如果 a 为 nil,则返回默认值 b。

所以你的函数可能看起来像这样:

    func numberOfObjectsInMyArray() -> Int {
        return (myArray?.count ?? 0)
    }

我同意其他人的观点,这可能是一个坏主意,原因有很多(例如,当实际上根本没有数组时,让它看起来有一个计数为“0”的数组)但是嘿,即使是糟糕的想法也需要实施。

编辑:

所以我添加这个是因为在我发布这个答案两分钟后,我遇到了一个完全按照作者想要做的事情的理由。

我正在 Swift 中实现 NSOutlineViewDataSource 协议。协议要求的功能之一是:

optional func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int

该函数要求您返回 item 参数的子代数。在我的代码中,如果项目有任何子项,它们将存储在一个数组中,var children: [Person]?

在我实际将一个子元素添加到数组之前,我不会初始化该数组。

换句话说,在我向 NSOutlineView 提供数据时,children 可能是 nil 或者它可以被填充,或者它可能曾经被填充但随后从其中删除了所有对象,在在这种情况下它不会是nil,但它是count 将是0。 NSOutlineView 不关心children 是否为nil - 它只想知道显示itemchildren 需要多少行。

因此,在这种情况下,如果 childrennil,则返回 0 非常有意义。调用该函数的唯一原因是确定 NSOutlineView 需要多少行。它不关心答案是0,因为children 是nil 还是因为它是空的。

return (children?.count ?? 0) 会做我需要的。如果childrennil,它将返回0。否则它将返回count。完美!

【讨论】:

  • 此答案中说明的 nil 合并运算符的使用是 OP 所述问题的最干净的解决方案(最佳答案)。您可能会质疑 API 的选择,但对于遗留代码,那是另一回事。
【解决方案2】:

这看起来是更简单的方法。

Objective-C 代码更短只是因为nil 也是 0 的一种形式,是一种基于 C 的语言。

因为 swift 是强类型的,所以你没有这样的速记。在这种特定情况下,它需要更多的努力,但总的来说,它可以为您省去大部分由松散输入引起的头痛。


关于特定情况,是否有理由首先将数组设为可选?你可以只有一个空数组。像这样的东西可能对你有用:

var myArray: Array<String> = []

func numberOfObjectsInMyArray() -> Int {
   return myArray.count
}

(Source for this information)

【讨论】:

  • 我喜欢! Swift 会确保 myArray 总是有一个值。太好了,谢谢。
  • 因为 nil 值表示尚未设置的数组与计数为 0 的数组。
【解决方案3】:

使用optional作为返回值怎么样?

var myArray: Array<String>?

func numberOfObjectsInMyArray() -> Int? {
    return myArray?.count
}

我觉得这样比较安全。

(Source for this information)

【讨论】:

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