Это был бы способ сделать это в Swift 3:
var parentView: View! = view
while parentView != nil {
// Do stuff
parentView = parentView.parent
}
Если вы хотите сгруппировать рамочные прогрессии вещей рядом с while
, а не в конце блока, вы можете использовать defer
, как это :
var parentView: View! = view
while parentView != nil {
defer { parentView = parentView.parent }
// Do stuff
}
Если вы хотите ограничить сферу parentView
, вы можете инкапсулировать все в do
блоке:
do {
var parentView: View! = view
while parentView != nil {
defer { parentView = parentView.parent }
// Do stuff
}
}
Но это довольно громоздким, чтобы вы могли определить новую обобщенную функцию для подобных циклов, например:
func kindaCStyleLoop<T>(first: T, obtainNext: T -> T?, action: T ->()) {
var current: T! = first
repeat {
action(current)
current = obtainNext(current)
} while current != nil
}
kindaCStyleLoop(view, obtainNext: { $0.parent }) {
// Do stuff with $0
}
И последний тот, который опирается на GeneratorType
и SequenceType
для того, чтобы, используя синтаксис-в-петле :
struct CStyleGenerator<T> : GeneratorType, SequenceType {
let getNext: T -> T?
var current: T!
init(first: T, getNext: T -> T?) {
self.getNext = getNext
self.current = first
}
mutating func next() -> T? {
defer {
if current != nil {
current = getNext(current)
}
}
return current
}
}
for parentView in CStyleGenerator(first: view, getNext: { $0.parent }) {
// Do stuff with parentView
}
Это действительно ** не Apple, ** который не любит C-петли, но [Эрика Садун] (https://github.com/apple/swift-evolution/blob/master/proposals/0007-remove-c-style-for-loops.md), Энди Матушак (Академия Хана), Кит Смайли (Лейф) и другие в списке рассылки. Крис Лэттнер (Apple) просто открыт для них. Наконец, комитет согласился удалить его. – adib
Пожалуйста, не добавляйте решение в качестве «Обновить» к вопросу. Если вы хотите поделиться своим решением, вы можете отправить ответ. – FelixSFD
@FelixSFD благодарит за консультацию, извлек это, чтобы ответить – brigadir