Мне часто нравится, как в инициализаторах для struct
с, enum
с и protocol
с я могу написать что-то вроде self = someValue
. Это замечательно, когда у меня есть некоторые предопределенные значения или я клонирую существующее значение.
Однако этот синтаксис не работает для class
es. Я тоже не могу понять почему.
Если проблема заключается в двойной инициализации, компилятор Swift знает, если, когда и где я вызываю обозначенные super
или self
инициализаторы, поэтому он знает, завершил ли я инициализацию этого экземпляра.
Если проблема заключается в том, что я еще не вызвал назначенный инициализатор, тогда все должно быть в порядке, потому что я бы просто сделал этот экземпляр ссылкой на другой (указатель 2 vars 1).
Если проблема заключается в том, что одновременный доступ мог вызвать инициализацию self
, то это бессмыслица, потому что мы в инициализаторе, а Swift инициализаторы не восприимчивы к этому .
И после всего, что я обнаружил, я могу обойти это с помощью одноразового протокола:
class MyClass {
let content: String
init(content: String) {
self.content = content
}
convenience init(from1 other: MyClass) {
self = other // Cannot assign to value: 'self' is immutable
}
}
protocol MyProto {}
extension MyClass: MyProto {}
extension MyProto {
init(from2 other: Self) {
self = other
}
}
let foo = MyClass(content: "Foo")
print(MyClass(from1: foo)) // Never would've compiled in the first place
print(MyClass(from2: foo)) // Perfectly OK!
Так почему же это запрещено в общем использовании, но разрешено в расширениях протокола?