Недавно я экспериментировал с операторами присваивания в Swift и столкнулся с проблемой, от которой я не мог найти решение.Можно ли инициализировать переменную с помощью специального оператора присваивания?
Рассмотрит следующую архитектуру:
struct Box<T> {
let value: T
}
struct MyStruct {
let myProperty: String
init(boxedProperty: Box<String>) {
self.myProperty = boxedProperty.value
}
}
Кажется довольно простым, но представьте себе, что MyStruct
принимает 20 коробочного свойства - каждый из них требует «распаковки» путем доступа к value
свойству Box
экземпляра. Теперь представьте себе 20 версий MyStruct
.
Это привело бы к сотням .value
линий, которых довольно много. Вместо этого, чтобы уменьшить беспорядок кода, я хотел бы использовать пользовательский оператор присваивания, который неявно «распаковывает» код Box
и присваивает его значение переменной.
Рассмотрим простой пример (без поддержки диспозитивности и т.д.):
infix operator <|= {
associativity right
precedence 90
assignment
}
func <|= <T>(inout lhs: T, rhs: Box<T>) {
lhs = rhs.value
}
В идеале я хотел бы использовать <|=
оператора сразу же, как это:
init(boxedProperty: Box<String>) {
self.myProperty <|= boxedProperty
}
Но, к сожалению (и вполне предсказуемо?), это не работает, так как переменная myProperty
не инициализируется перед использованием в функции:
error: variable 'self.myProperty' passed by reference before being initialized
self.myProperty <|= boxedProperty
^
Могу ли я обеспечить компилятор, чтобы моя операторская функция assignment
всегда инициализировала переменную (a.k.a. его операнд lhs
)? Кроме того, если у вас есть идея другого подхода, не стесняйтесь комментировать.
Примечание: Фактический случай является более сложным и требует более «распаковка», чем просто доступ к value
propterty в виде Box
структуры.
Ваша проблема не в использовании массивов ящиков и свойств? init (boxedProperties: [Box]) {self.myProperties = boxedProperties.map {% 0.value}} При этом 20 или 200 свойств, неважно. –
GoZoner
@GoZoner No. Это на самом деле 'init (anEnumValue: MyEnum)' в реальном случае. Значение enum содержит разные связанные значения, которые должны быть двойными - «unboxed». – akashivskyy
В отличие от других операторов присваивания Swift (кроме фактического назначения с '=') вам не нужен параметр 'inout', потому что, как вы знаете, вы никогда не ссылаетесь на значение. Но на поверхности вы торгуете: 'self.myProperty <| = boxedProperty' для' self.myProperty = boxedProperty.value'. Я не понимаю преимущества для оператора в этом случае, но я согласен признать, что не вижу вашей реальной проблемы. – GoZoner