I would like my class to have a stored property that can be assigned immutable arrays. If I do this:
class MyClass{
var myItems:[String]
}
I can assign different arrays to my property, but the arrays will be mutable. If I do this:
class MyClass{
let myItems:[String]
}
My array is immutable, but I can't ever change what's assigned to it. Is there any way to have my cake not mutate it too?
The best I've come up with is creating a wrapper around the array, then using that type for the property, like so:
class MyClass{
struct ImmutableWrapper{
let array:[String]
}
var myItems:ImmutableWrapper
}
…which is not exactly elegant.
The question is oddly posed, since your first myItems
is not an array of various arrays, it's just an array of Strings. However, I'll try to discuss the matter in a more general way.
Swift does not distinguish mutable from immutable arrays in the way Cocoa NSArray does. But why do you need this? Cocoa needs it because an NSArray is a class, so if it were mutable, it could be changed behind MyClass's back. But in Swift, Array is a value type, so that can't happen.
So what's the problem you are really trying to solve? You should ask yourself what contract you are trying to get outside objects to fulfill, and try to write that contract into the structure of MyClass. Your array of structs is a perfectly reasonable approach. I think, though, that what you're after here might actually be privacy, not immutability. For example, I might say this:
class MyClass{
private var myItemsHidden = [String]()
var myItems:[String] {
get {
return myItemsHidden
}
set {
myItemsHidden = newValue
}
}
}
Now, assuming MyClass is alone in its own file (because private
in Swift means private to a file), myItemsHidden
can be manipulated in any way you like from inside MyClass, so presumably MyClass knows not to mutate any subarrays or whatever it is you are trying to prevent. It is up to MyClass what it allows itself to do with myItemsHidden
.
But from outside MyClass, myItemsHidden
does not exist; there is only myItems
, and the only thing anyone can do to it is get it and set it. (If they get it and change it, the original is unaffected. They cannot mutate the original.) If your purpose is to prevent anyone from outside setting myItems
at all, delete the setter function:
class MyClass{
private var myItemsHidden = [String]()
var myItems:[String] {
get {
return myItemsHidden
}
}
}
Now myItems
is merely a dispensed (vended) array and no more.
If the idea is that other classes should be allowed to add new arrays to an array of arrays, you could add a MyClass method that lets them do that. In other words, now that this thing is private, it is up to you what kind of access you give others to it. MyClass becomes the gatekeeper for what other classes can do with this value, because the value itself is hidden behind the private
wall.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments