Arrays Swift中的可选数组与空数组

Arrays Swift中的可选数组与空数组,arrays,swift,optional,Arrays,Swift,Optional,我在Swift中有一个简单的Person类,看起来像这样: class Person { var name = "John Doe" var age = 18 var children = [Person]? \\ init function goes here, but does not initialize children array } var children = [Person]() 我可以简单地声明它并将其初始化为空数组,如下所示: class

我在Swift中有一个简单的
Person
类,看起来像这样:

class Person {
    var name = "John Doe"
    var age = 18
    var children = [Person]?

    \\ init function goes here, but does not initialize children array
}
var children = [Person]()
我可以简单地声明它并将其初始化为空数组,如下所示:

class Person {
    var name = "John Doe"
    var age = 18
    var children = [Person]?

    \\ init function goes here, but does not initialize children array
}
var children = [Person]()
我正在努力决定哪种方法更好。将数组声明为可选数组意味着它根本不会占用任何内存,而空数组至少为其分配了一些内存,对吗?因此,使用可选数组意味着至少可以节省一些内存。我想我的第一个问题是:这里真的有任何实际的内存节省,或者我的假设是错误的

另一方面,如果它是可选的,那么每次尝试使用它时,我都必须在添加或删除对象之前检查它是否为
nil
。因此,那里会有一些效率损失(但我想不会太多)

我有点喜欢可选的方法。不是每个
人都会有孩子,所以为什么不让
孩子
成为
nil
,直到
人决定定居并抚养一个家庭


无论如何,我想知道一种方法或另一种方法是否还有其他具体的优点或缺点。这是一个会反复出现的设计问题。

Swift旨在利用可选值和可选展开。

还可以将数组声明为nil,因为它将为您节省非常小(几乎不可见)的内存量

为了让Swift的设计模式满意,我会选择一个可选数组,而不是一个表示nil值的数组:)

我也认为

if let children = children {

}
看起来比:

if(children != nil){

}

我将用Yordi做一个相反的例子——一个空数组清楚地表明“这个人没有孩子”,这将为您节省大量的麻烦
children.isEmpty
是一种检查孩子是否存在的简单方法,您不必打开包装或担心意外的
nil


另外,需要注意的是,将某些内容声明为可选并不意味着它占用零空间-这是
.None
情况下的
可选

在空数组或可选数组之间进行选择的能力使我们能够应用从语义角度更好地描述数据的数组

我会选择:

  • 如果列表可以为空,但它是一个暂时状态,并且最后应该至少有一个元素,则为空数组。非可选性表明数组不应为空

  • 如果列表在容器实体的整个生命周期内可能为空,则为可选。如果是可选的,则表明数组可以为空
让我举几个例子:

  • 带有主数据和详细信息的采购订单(每个产品一个详细信息):采购订单可以有0个详细信息,但这是一个暂时状态,因为拥有一个带有0个产品的采购订单是没有意义的
  • 有孩子的人:一个人一生不能有孩子。这不是一个暂时的状态(虽然也不是永久的),但使用可选的,很明显,一个人没有孩子是合法的

请注意,我的观点只是关于使代码更加清晰和自我解释-我认为在选择一个选项或另一个选项时,在性能、内存使用等方面没有任何显著差异。

有趣的是,我们最近很少讨论工作中的同一问题

有人认为,两者之间存在细微的语义差异。例如,
nil
意味着一个人没有孩子,但是
0
意味着什么呢?这是否意味着“有孩子,他们全部都有”?正如我所说,在代码中使用此模型时,纯语义“没有子对象”和“没有子对象”没有任何区别。在这种情况下,为什么不选择更多的直截了当和更少的后卫让?-y方法

有人建议保持
nil
可能有一种迹象表明,例如,当从后端获取模型时,出现了一些错误,我们得到了错误,而不是子对象。但我认为模型不应该尝试使用这种类型的语义,
nil
不应该被用作过去某些错误的指示

我个人认为这个模型应该尽可能的愚蠢,在这种情况下最愚蠢的选择是空数组

有一个可选选项将使您将该
拖到几天结束,并反复使用
保护let
如果let
??

您必须为
NSCoding
实现提供额外的展开逻辑,您必须执行
person.children?count??0
而不是直接的
person.children.count
当您在任何视图控制器中显示该模型时

所有这些操作的最终目标是在UI上显示一些东西。 你真的会说

对于
nil
和空数组,“此人没有子项”和“此人有0个子项”?我希望你不会:)

最后一根稻草 最后,这是我最有力的论点

  • UIView
    子视图
    属性的类型是什么:
  • SKNode
    子属性的类型是什么:
在Cocoa框架中有很多这样的例子:还有更多

即使来自纯粹的斯威夫特世界:尽管这可能有点牵强

为什么一个人有
nil
孩子是可以的,但是没有
SKNode
?对我来说,这个类比是完美的。嘿,甚至
SKNode
的方法名也是
children
:)

我的观点是:将这些数组保留为可选数组肯定有一个明显的原因,就像一个非常好的数组一样,否则空数组提供了相同的语义