2017-07-14 12 views
0

いくつかの一般的な項目を持つ構造体にカスタムflatMapを実装しようとしています。 flatMapは、指定された変換関数を使用するアイテムに対してちょうどSwift.flatMapになります。ここのコードは少し工夫されていますが、標準ライブラリバージョンでエラーが発生しないのはなぜですか?SwiftカスタムflatMapの実装でエラーが発生する一般的なパラメータを推測できません

flatMapの実装に欠けているものがありますか?

struct Wrapper<T:NSObject> { 

    let items:[T] 

    func flatMap<U>(_ transform:(T) -> U?) -> Wrapper<U> { 
     let newItems = items.flatMap { transform($0) } 
     return Wrapper<U>(items: newItems) 
    } 
} 

protocol Something {} 

let wrapper = Wrapper<UIView>(items: [UIView()]) 

// Using standard library flatMap 
wrapper 
    .items 
    .flatMap { $0 as? Something } // ✅ No error 
    // .. 

// Using custom flatMap 
wrapper 
    .flatMap { $0 as? Something } // ERROR: Generic parameter 'U' could not be inferred 
    // .. 
+2

なぜ 'T 'に' NSObject'制約がありますか? 'Something'はプロトコルなので、' NSObject'から継承しないので、 'Wrapper 'を持つことはできません。 – Hamish

+0

'extension UIView:Something {}'のようなコードのどこかに適合性があるかもしれません。その場合、キャストを試みるのが理にかなっています。 –

+0

しかし 'struct Foo:Something'があったら?これは 'Something'にキャストできますが、' NSObject'を継承しません。本当に 'NSObject'制約が必要な場合は、' wrapper.flatMap {$ 0 as? NSObject&Something} '(Swift 4)を参照してください。 – Hamish

答えて

2

SomethingNSObjectに準拠していません。

スウィフト4は、を含むすべてのパラメータを調べることで、flatMap関数で使用される汎用パラメータUの制約を自動的に推論します。 UWrapperの汎用パラメータとして使用され、U: NSObjectが必要です。 SomethingNSObjectのサブクラスではありません。

エラーメッセージは間違いです。

+0

サンプルコードから "Wrappable"を削除しました(私が投稿した後はかなり速くなりました)。 –

+1

'Something'はまだSwiftプロトコルであり、' NSObject'のサブクラスではありません。 – Palle

+0

答えを更新しました。問題はまだ同じです。 – Palle

関連する問題