Swift计算属性以返回基础数组的副本

时间:2014-09-11 23:40:53

标签: swift

我有一个用Objective-C编写的模型类,我正在转换为Swift。它内部包含NSMutableArray,但getter的方法签名以及实际返回值为NSArray。调用时,它会创建一个不可变副本来返回。

基本上,我希望调用者能够迭代/检查容器,但不能修改它。我有这个测试片段:

class Container {
    internal var myItems = [String]()

    func sayHello() {
        "I have: \(myItems)"
    }
}

let cont = Container()

cont.myItems.append("Neat") // ["Neat"]

cont.sayHello() // This causes sayHello() to print: "I have: [Neat]"

var isThisACopy = cont.myItems

isThisACopy.append("Huh") // ["Neat", "Huh"]

cont.sayHello() // This ALSO causes sayHello() to print: "I have: [Neat]"

我一直试图找到一种方法来覆盖myItems的getter,以便它返回一个不可变的副本,但似乎无法确定如何。

尝试#1

这会产生编译器错误:Function produces expected type '_ArrayBuffer<(String)>'; did you mean to call it with '()'?

internal var myItems = [String]() {
    var copy = [String]()
    for item in ... { // What to use in the ...?
        copy.append(item)
    }
    return copy
}

尝试#2

这也会产生编译器错误,因为我(可以理解)重新定义生成的getter Invalid redeclaration of 'myItems()'

internal func myItems() -> [String] {
    var copy = [String]()
    for item in myItems {
        copy.append(item)
    }
    return copy
}

2 个答案:

答案 0 :(得分:4)

试试这个:

class Container {
    private var _myItems: [String] = ["hello"]
    internal var myItems: [String] {
        return _myItems
    }
}

let cont = Container()
cont.myItems.append("Neat") //not allowed

它使用私有存储属性和返回不可变副本的计算属性。存储的属性不可能使用自定义getter。

答案 1 :(得分:1)

expose mutable properties as immutable的更好方式:

class Container {
    private (set) internal var myItems: [String]
}