young
(rtSwift)
1
// 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?
sjavora
(Šimon Javora)
2
- 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 Like
Nevin
3
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.
3 Likes
sjavora
(Šimon Javora)
4
I found this some time ago:
3 Likes
young
(rtSwift)
5
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?
Lantua
6
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.
4 Likes
young
(rtSwift)
7
Oh I see: it's to allow a let to be initialized some time later...
young
(rtSwift)
8
swiftc 5.3
static output.S.c.getter : Swift.Int:
push rbp
mov rbp, rsp
mov rax, qword ptr [rip + (static output.S.c : Swift.Int)]
pop rbp
ret
static output.S.d.getter : Swift.Int:
push rbp
mov rbp, rsp
mov eax, 1234
pop rbp
ret
not the same, 1234 is stored in memory somewhere?
static output.S.c : Swift.Int:
.quad 1234
swiftc nightly:
static output.S.c.getter : Swift.Int:
mov eax, 1234
ret
static output.S.d.getter : Swift.Int:
mov eax, 1234
ret
become just 2 instructions!
5 Likes
Nobody1707
(Nobody1707)
9
Ooh, is the optimizer finally getting rid of the pointless stack pointer shuffling in leaf functions?