I am adding some syntactical sugar to my app, and I came across an 'inconsistency'. There is probably good reason for it, but is there way to clean the implementation a little. I a doing this to provide a single place to set/get some properties.
enum MyType: String {
case Unknown, First, Second
var enabled: Bool {
set { UserDefaults.standard.set(newValue, forKey: self.rawValue) }
get { return UserDefaults.standard.bool(forKey: self.rawValue) }
}
}
Now I can use the enum values to get the defaults
if MyType.First.enabled {
........
}
But I cannot directly set the value:
MyType.First.enabled = true
elicits 'cannot set property, First is not assignable'
but I can get away with
var type = MyType.First
type.enabled = true
Is there a simple way to use the one-line method?
The issue is that enums are value types, so when you call the setter of enabled on MyType.First, you mutate First as well. If you don't assign value types to a mutable variable explicitly, they are considered immutable. This is why if MyType.First.enabled {...} doesn't work, but
var type = MyType.First
type.enabled = true
does work.
If you mark the setter as nonmutating, the issue is resolved, since the compiler will now know that you aren't mutating a value type when calling the setter on its property.
enum MyType: String {
case unknown, first, second
var enabled: Bool {
nonmutating set { UserDefaults.standard.set(newValue, forKey: self.rawValue) }
get { return UserDefaults.standard.bool(forKey: self.rawValue) }
}
}
P.S.: the Swift naming convention for enum cases is lowerCamelCase, since they are not types themselves and only types should be UpperCamelCase. I've modified your MyType enum accordingly.
By adding the nonmutating keyword to the set method you are telling the compiler that the set method will not modify the enclosing type, that is the enum MyType in this case
enum MyType: String {
case Unknown, First, Second
var enabled: Bool {
nonmutating set { UserDefaults.standard.set(newValue, forKey: self.rawValue) }
get { return UserDefaults.standard.bool(forKey: self.rawValue) }
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With