2017-04-04 5 views
2

私はこのコードでここで紛失している単純なものがあるかどうか、または私が望むことをするのを妨げているスウィフトトリッキーの組み合わせであるかどうかを知りたいと思います。プロトコルのジェネリックプロパティに割り当てることができません

私はFooプロトコルを実装するタイプがStringIdentifiableに限り、それは準拠して、任意のタイプのentity財産を含有させることだ:スウィフト3.1、この「任意のタイプ」の部分wouldn't be possible場合のよう

protocol StringIdentifiable { 
    var id: String? { get } 
} 

protocol Foo: class { 
    associatedtype AnyStringIdentifiable: StringIdentifiable 
    var entity: AnyStringIdentifiable? { get set } 
} 

associatedtypeを使用しないでください。先に、Fooプロパティを必要とする別のプロトコルがあるとしましょう。しかし、Fooは一般的なものなので、"汎用プロトコルは一般的な制約としてのみ使用できます"のため、われわれはそれを行うことはできません。型消去の混乱を避けるためにしようと、私は私の第二のプロトコルで別のassociatedtypeを使用することを決めたとコンパイラが文句はありません:

protocol Bar { 
    //var foo: Foo { get set } // can't do because Foo is generic 
    associatedtype AnyFoo: Foo 
    var foo: AnyFoo { get set } 
} 

しかしを、今、私は、コンパイラは文句を言うでしょうfooで何かを設定しようとします。

extension Bar { 
    func setEntity(_ entity: StringIdentifiable) { 
    foo.entity = entity 
    } 
} 

エラーが「_?」がタイプするタイプ「StringIdentifiable」の値を割り当てることができませんで

注:この質問のコードは、遊び場で試すことができます。 foo.entityはタイプAnyFoo.AnyStringIdentifiableであるため

答えて

3

あなたは、あなたがfoo.entityを設定するときのタイプが正しいことを確認するためにAnyFoo.AnyStringIdentifiableを使用することができますバーの中で、この

//: Playground - noun: a place where people can play 

import Cocoa 

protocol StringIdentifiable { 
    var id: String? { get } 
} 

protocol Foo: class { 
    associatedtype AnyStringIdentifiable: StringIdentifiable 
    var entity: AnyStringIdentifiable? { get set } 
} 

protocol Bar { 
    //var foo: Foo { get set } // can't do because Foo is generic 
    associatedtype AnyFoo: Foo 
    var foo: AnyFoo { get set } 
} 

extension Bar { 
    func setEntity(_ entity: AnyFoo.AnyStringIdentifiable) { 
     foo.entity = entity 
    } 
} 

のようにそれを行うことができます。

+1

haha​​は非常にハッキリですが、それは働きます:) – Gobe

+0

これはちょうどあなたを助けるタイプのシステムです!それについて考えてみましょう。あるバーについては、それは 'Foo'である' AnyFoo'を持っています。 'AnyFoo'は常に' StringIdentifiable'である 'AnyStringIdentifiable'を持っています。 2つのものが両方とも 'AnyFoo'であるという理由だけで、両方が同じ' AnyStringIdentifiable'を共有しているわけではありません。だからあなたが必要とする 'StringIdentifiable'のタイプを知る' Bar'の観点からは、十分な知識がありません。しかし、 'Bar'は' Foo'のタイプを知っていて、 'Foo'は' StringIdentifiable'のタイプを知っています。ですから、あなたはそれを「AnyFoo.AnyStringIdentifiable'」というように扱わなければなりません。 –

+0

今私はそれに同意しない...まず、Any stuffは関連する型である。私はプロトコル自体の外でこれらの型を参照できるという事実は気に入らない。バーの内側からAnyStringIdentifiableを呼び出すことは非常に奇妙です。第二に、私はBarの観点から十分な知識があると信じています、BarはそれがFooであることを知っています。そしてFoosはStringIdentifiableな何かを持っています。彼らの前に「Any」が付いている(関連タイプとして)という事実は、(SR-522が対処されていれば必要ではないが) – Gobe

関連する問題