4

ジェネリック型の要件を参照型だけに制限しようとして問題が発生しています。コード例を次に示します。

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

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

4

2 に答える 2

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)

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

于 2016-12-01T15:37:28.373 に答える
0

簡単な答えは、プロトコルであるジェネリック型を持つことはできないということです。

構文を書き出すと、これがどのように機能するかが明確になります。 class/struct GenericType<TypeName: TypeConstraints> {}

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

タイプをクラスとして採用することを要求するプロトコルは、すべての採用者がクラスであることを意味しますが、プロトコル自体はまだタイプではありません。

ある時点でジェネリックがプロトコルをサポートする可能性はありますが、プロトコルまたはジェネリックへの一般的なアプローチを変更する必要があります。あなたの特定の例は、舞台裏での少量の作業で可能かもしれませんが、これはある時点で実装される可能性があります。

彼らの方向性を知りたい場合は、The Generics Manifesto を参照してくださいスキミングして、ユースケースに直接関連するものは見つかりませんでしたが、かなり具体的であるため、ドキュメントのパラメーターに含まれていない可能性があります。

于 2016-12-01T00:56:49.707 に答える