2016-03-23 15 views
3

AppleはCループが気に入らないようですが、それ以上のアプローチはしていません。いくつかのビューからUI階層のルートに移動するループがあります:Swift 3:(;;)ループの記述方法

for var parentView = view; parentView != nil; parentView = parentView.parent { 
    ... 
} 

スウィフト3の方法でこれを書く方法は?

+1

それは本当に**ないAppleの**誰もCループを好まないが、[Erica Sadun](https://github.com/apple/swift-evolution/blob/master/proposals/0007-remove-c-style-for-loops.md)、Andy Matuschak(Khan Academy)、Keith Smiley(Lyft)などがメーリングリストに参加しました。 Chris Lattner(Apple)は彼らにただ開いています。最後に、委員会はそれを削除することに同意した。 – adib

+0

解決策を質問に「更新」として追加しないでください。独自のソリューションを共有したい場合は、回答を投稿することができます。 – FelixSFD

+1

@FelixSFDアドバイスありがとうございました。回答が得られました – brigadir

答えて

2

これはスウィフト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ブロック内のすべてカプセル化することができます:

0を

しかし、あなたはこのように、同様のループのための新しい汎用関数を定義することができますので、それは非常に冗長です:

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 
} 

そしてのためのインループ構文を使用して有効にするGeneratorTypeSequenceTypeに依存している最後の1 :例えば

+0

オプションはwhileループ内で安全にアンラップすることができます – pkacprzak

+1

明示的なオプションの代わりに暗黙のオプションを使用するように答えを更新しました。 – Valentin

+0

parentViewがnilになったときにクラッシュします。これまでと同じままにしておくこともできますし、whileループ内のオプションをアンラップすることもできます。 – pkacprzak

0
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 
} 

for view in views where view.superview != nil { 
} 
+0

'views'とは何ですか? – brigadir

1

コアー電気ショック療法が、あまりにも遅答え:そこには、ビルトインされているソリューションを提供スウィフト3での機能:

public func sequence<T>(first: T, next: (T) -> T?) -> UnfoldSequence<T, (T?, Bool)> 
public func sequence<T, State>(state: State, next: (inout State) -> T?) -> UnfoldSequence<T, State> 

我々は、この方法でそれらを使用することができます。

sequence(first: view, next: { 
    // do something with $0... 
    return $0.superview 
}) 
+0

あなたがそれを使用していない場合はfor forは必要ありません。シーケンス機能のみを使用してください。 – Binarian

+1

true!訂正ありがとう – brigadir

関連する問題