// somethiong similar to SwiftUI.PreferenceKey
protocol SimpleProtocol {
associatedtype Value
static var value: Value { get }
}
struct SomeSimple: SimpleProtocol {
// 1) why cannot be a `let`, why is `var` used? which lead to some unexpect: I can re-assign to this property!
static var value = 100
// so should I be doing this? Is this the proper/correct way?
// static var value: Int { 100 }
}
// Oh no, can re-assign to a get only value?! Why can I violate the protocol's definition?
SomeSimple.value = 123
print(SomeSimple.value) // print 123!
So I have two questions: 1) at the protocol implementation, why is a get-only property a var, not a let? Look confusing reading the code. 2) why can I re-assign a get-only property to some different value?
at the protocol implementation, why is a get-only property a var , not a let ?
It absolutely can be a let. Xcode's fixits insert vars in such cases though.
why can I re-assign a get-only property to some different value?
You are accessing value through SomeSimple, not SimpleProtocol. And in the context of SomeSimple, the value is mutable. If you changed it to let, you could not reassign it.
1. You can use let in the struct if you want S.value to be immutable.
2. The protocol does not say the property is get-only—in fact there is no way to do that. The protocol simply does not require a setter.
3. I believe I have seen it mentioned that a static computed property is more efficient than a static stored property, but I don’t have a citation at hand.
Ah, my example isn't exactly what got me confused. Value was actually Int?:
struct SomeSimple: SimpleProtocol {
static var value: Int?
}
That was what I did at first, relying on value getting default of nil, then I tried changing var to let without explicitly assigning nil and the compiler did not like that:
// somethiong similar to SwiftUI.PreferenceKey
protocol SimpleProtocol {
associatedtype Value
static var value: Value { get }
}
struct SomeSimple: SimpleProtocol {
static let value: Int? // !! without = nil
}
print(SomeSimple.value ?? -1)
So I am clear now it can be a let.
But now I want to know: why when value was:
var value: Int?
value is nil automatically.
but if it's:
let value: Int?
I get error:
static var declaration requires an initializer expression or getter/setting specifier
So why a var of optional gets a nil value automatically, but a let do not?
I don't think there's any intentional code that wants let value to default to nil. Since that would count as an initialization, you can't ever change that let to a non-nil value.
There are actually people who want to get rid of the default nil on the var side, but given the src compat, that's quite unlikely.