Fast computed property to return a copy of the underlying array

I have a model class written in Objective-C, which I convert to Swift. It contains the NSMutableArray internally, but the method signature for the receiver, as well as the actual return value of the NSArray . When called, it creates an immutable copy to return.

Essentially, I want the callers to be able to iterate / validate the container but not modify it. I have this test fragment:

 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]" 

I tried to find a way to override getter for myItems so that it returns an immutable copy, but cannot determine how.

Attempt # 1

This leads to a compiler error: Function produces expected type '_ArrayBuffer<(String)>'; did you mean to call it with '()'? 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 } 

Attempt # 2

This also creates a compiler error, because I (understandably) override the generated getter Invalid redeclaration of 'myItems()' :

 internal func myItems() -> [String] { var copy = [String]() for item in myItems { copy.append(item) } return copy } 
+6
source share
2 answers

Try the following:

 class Container { private var _myItems: [String] = ["hello"] internal var myItems: [String] { return _myItems } } let cont = Container() cont.myItems.append("Neat") //not allowed 

It uses a private stored property and a computed property that returns an immutable copy. It is not possible for a stored property to use custom getters.

+4
source

The best way to show mutable properties as immutable :

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

Source: https://habr.com/ru/post/975161/


All Articles