2016-11-30 6 views
2

ジェネリックタイプの要件を参照タイプに制限しようとすると問題が発生します。ここではいくつかのサンプルコードです:Swiftジェネリックリファレンスタイプ

class WeakHolder<Element: AnyObject> { 
    weak var element: Element? 

    init(element: Element) { 
     self.element = element 
    } 
} 

protocol Animal: class { } 

class Dog: Animal { } 

let dog: Animal = Dog() 
let holder = WeakHolder<Animal>(element: dog) // Error: Using "Animal" as a concrete type conforming to protocol 'AnyObject' is not supported. 

私は<Element: class>に、一般的な要件を変更した場合、私はエラーclass constraint can only appear on protocol declarationsを取得します。

これはジェネリックの制限ですか?プロトコルをクラスとしてマークするだけで、そのプロトコルへの弱い参照を持つことができます。ジェネリックには同等のものはありませんか?

+0

Dogはプロトコルであるため、DogはAnyObjectではありません –

+0

私の小さな経験に基づいて、これはswift 2.3のようにジェネリックには限界があります。あなたはプロトコルの代わりにクラスを使用してこれを修正することができるかもしれません –

+0

私の実装でプロトコルを使用する必要があります。 – Mark

答えて

0

単純な答えは、プロトコルであるジェネリックタイプを持つことができないということです。構文は、これがどのように機能するか、それは明らかに書き出す

:クラスであることを採用するタイプが必要な class/struct GenericType<TypeName: TypeConstraints> {}

let thing = GenericType<Type>() where Type is a class or struct that adheres to any constraints

Aプロトコルは、任意の採用がクラスであることが、議定書自体はまだありませんタイプ。

ジェネリックは、ある時点でプロトコルをサポートする可能性がありますが、一般的なアプローチをプロトコルまたはジェネリックに変更する必要があります。あなたの具体的な例は、場面の背後にある少量の作品では可能かもしれませんが、ある時点で実装される可能性があります。

方向性を確認したい場合は、The Generics Manifestoをご覧ください。それをスキミングすると、私はあなたのユースケースに直接関係するものは見つかりませんでしたが、かなり具体的なので、ドキュメントのパラメータには含まれないかもしれません。

+0

ああ、一般化されたクラス制約は、私が探しているものです。これはSwiftの将来のバージョンで検討されていることを知っています。 – Mark

0

私の特定のケースで働いていた別の解決策は以下の通りです:

class WeakHolder<Element: AnyObject> { 
    weak var element: Element? 

    init(element: Element) { 
     self.element = element 
    } 
} 

protocol Animal: class { } 

class Dog: Animal { } 

let dog: Animal = Dog() 
let holder = WeakHolder<AnyObject>(element: dog as AnyObject) 

要素にアクセスして、私は単に私のプロトコルに戻ってダウンキャストを実行する必要があります。もちろん、このクラスを値型で使用するときにはコンパイル時の安全性が失われますが、それは私の状況では問題になりません。