Hey folks,
when I try to access a computed property during init()
, Swift always executes the "default" implementation instead of the constrained version. When I access the property on an already initialized instance, the (imho) "correct" version gets called.
The same happens when defining check
as a function as opposed to a computed property.
Is this working as designed? How would I ensure that the constrained version gets called during init?
Reproducible example: (copy to any playground)
struct NonEquatableStruct {
var a: Int
init() {
a = 10
}
}
struct EquatableStruct: Equatable {
var a: Int
init() {
a = 10
}
}
class EquatableClass: Equatable {
static func == (lhs: EquatableClass, rhs: EquatableClass) -> Bool {
return lhs.a == rhs.a
}
var a: Int
init() {
a = 10
}
}
class Checker<C> {
init() {
print("[\(C.self)]")
print("--- Checking in init ---")
print(check)
}
var check: Bool {
print("Default; neither Equatable nor AnyObject")
return false
}
}
extension Checker where C: Equatable {
var check: Bool {
print("Equatable")
return true
}
}
extension Checker where C: AnyObject {
var check: Bool {
print("AnyObject")
return true
}
}
extension Checker where C: AnyObject, C: Equatable {
var check: Bool {
print("AnyObject and Equatable")
return true
}
}
let checkNonEquatable = Checker<NonEquatableStruct>()
print("--- Accessor: ---")
print(checkNonEquatable.check, "\n")
let checkEquatable = Checker<EquatableStruct>()
print("--- Accessor: ---")
print(checkEquatable.check, "\n")
let checkEquatableClass = Checker<EquatableClass>()
print("--- Accessor: ---")
print(checkEquatableClass.check, "\n")
Console output:
[NonEquatableStruct]
--- Checking in init ---
Default; neither Equatable nor AnyObject
false
--- Accessor: ---
Default; neither Equatable nor AnyObject
false
[EquatableStruct]
--- Checking in init ---
Default; neither Equatable nor AnyObject
false
--- Accessor: ---
Equatable
true
[EquatableClass]
--- Checking in init ---
Default; neither Equatable nor AnyObject
false
--- Accessor: ---
AnyObject and Equatable
true
Expected behaviour:
The same accessor implementation gets called both during and after initialization.