我可以通过引用声明局部Array变量,以减少重复代码

时间:2018-07-03 22:45:48

标签: swift reference

所以我知道Swift数组是struct,所以它们是按值传递的

这是我的代码:

firstSnapshotListsecondSnapshotList均为[Snapshot]

    if datePicker == firstDatePicker {
        firstSnapshotList.removeAll()

        if let snapshots = SnapshotList.snapshotDict[dateKey] {
            for snapshot in snapshots {
                firstSnapshotList.append(snapshot)
            }
        }
    } else if datePicker == secondDatePicker {
        secondSnapshotList.removeAll()

        if let snapshots = SnapshotList.snapshotDict[dateKey] {
            for snapshot in snapshots {
                secondSnapshotList.append(snapshot)
            }
        }
    }

如您所见,如果if语句相同,则两个块相同,除了要修改的数组之外。

我想先声明一个变量,var snapshotList = *snapshot reference*, 然后如果我可以根据日期选择器将该引用设置为firstSnapshotListsecondSnapshotList,那么我的代码就是

if datePicker == firstDatePicker {
    snapshotList = firstSnapshotList
} else if datePicker == secondDatePicker {
    snapshotList = secondSnapshotList
}

snapshotList.removeAll()

if let snapshots = SnapshotList.snapshotDict[dateKey] {
    for snapshot in snapshots {
        snapshotList.append(snapshot)
    }
}

您可能会争辩说行数是相同的,所以它实际上并没有任何可读性或可维护性-对我来说这只是个人喜好,我认为第二个版本更有意义,主要是因为没有重复代码

但是,如果这只是Swift生活方式的一部分,我也可以接受。只是想知道是否有可能将变量声明为引用

3 个答案:

答案 0 :(得分:1)

  

数组与标准库中的所有可变大小集合一样,都使用写时复制优化。阵列的多个副本共享同一存储,直到您修改其中一个副本为止。发生这种情况时,要修改的阵列将用其唯一拥有的副本替换其存储,然后对其进行修改。有时会进行优化以减少复制量。

答案 1 :(得分:1)

您的代码可以简化到不需要减少代码重复的程度:

let newSnapshotList = SnapshotList.snapshotDict[dateKey] ?? []

if datePicker == firstDatePicker {
    firstSnapshotList = newSnapshotList
} else if datePicker == secondDatePicker {
    secondSnapshotList = newSnapshotList
}

但是为了回答这个问题,可以通过在现有函数中声明一个嵌套函数来完成此操作:

func overrideFromSnapshotDict(destination: inout [YourType]) {
    destination.removeAll()
    if let snapshots = SnapshotList.snapshotDict[dateKey] {
        for snapshot in snapshots {
            destination.append(snapshot)
        }
    }
}

if datePicker == firstDatePicker {
    overrideFromSnapshotDict(destination: &firstSnapshotList)
} else if datePicker == secondDatePicker {
    overrideFromSnapshotDict(destination: &secondSnapshotList)
}

答案 2 :(得分:1)

正如您所说,Swift数组是结构,它们确实作为值传递。您可以改为将数组作为inout参数传递给单独的方法:

func yourMethodName(_ array: inout [Snapshot]) {
    array.removeAll()

    if let snapshots = SnapshotList.snapshotDict[dateKey] {
        for snapshot in snapshots {
            array.append(snapshot)
        }
    }
}

然后仅在需要的地方调用该方法,如下所示:

if datePicker == firstDatePicker {
    yourMethodName(&firstSnapshotList)
} else if datePicker == secondDatePicker {
    yourMethodName(&secondSnapshotList)
}