、のがエラーを説明しましょう:
を考える:ここ
class Foo<T:Hashable> { }
class SubFoo<String> : Foo<String> { }
紛らわしい部分は、私たちが「文字列」の文字のコレクションを保持スウィフト定義された構造を意味することを期待していることです。しかし、そうではありません。
ここで、「String」は、新しいサブクラス「SubFoo
」を指定したジェネリック型の名前です。
class SubFoo<String> : Foo<T> { }
この行が宣言されていないタイプの使用などT
ためにエラーが発生します。私たちはいくつかの変更を加えた場合、これは非常に明白になります。
はその後、我々はこれに行を変更した場合:
class SubFoo<T> : Foo<T> { }
私たちが戻ってあなたがもともと持っていた同じエラーにしている、「T」「はハッシュ可能」に準拠していません。ここでは明らかです。なぜなら、Tは 'Hashable'に従う既存のSwiftタイプの名前を混乱させるものではないからです。明らかに 'T'は一般的なものです。
「文字列」と書くと、それは汎用タイプのプレースホルダ名でもあり、実際にはSwiftに存在するString
タイプではありません。
我々は、一般的なクラスの特定のタイプごとに異なる名前を使用する場合は、適切なアプローチはほぼ確実typealias
です:
class Foo<T:Hashable> {
}
typealias StringFoo = Foo<String>
これは完全に有効なスウィフトであり、それはうまくコンパイルします。
実際にサブクラス化し、ジェネリッククラスにメソッドやプロパティを追加することで、我々が望むものを代わりにした場合、我々は必要なものを私たちが必要なものに私たちの一般的な、より具体的になりますクラスまたはプロトコルです。元の問題に戻って
、最初のエラーを取り除くましょう:
は
class Foo<T: Hashable>
class SubFoo<T: Hashable> : Foo<T> { }
これは完全に有効なスウィフトです。しかし、それは特に我々がやっていることには役に立たないかもしれません。私たちは、次の操作を行うことはできません
唯一の理由は:String
はスウィフトクラスではないので、
class SubFoo<T: String> : Foo<T> { }
単純である - それは構造です。そして、これはどんな構造にも許されません。
我々はHashable
から継承する新しいプロトコルを記述する場合、我々はそれを使用することができます。
protocol MyProtocol : Hashable { }
class Foo<T: Hashable> { }
class SubFoo<T: MyProtocol> : Foo<T> { }
これは完全に有効です。
また、私たちが実際にHashable
から継承する必要はありませんのでご注意:
protocol MyProtocol { }
class Foo<T: Hashable> { }
class SubFoo<T: Hashable, MyProtocol> { }
また、これは完全に有効です。
ただし、何らかの理由で、Swiftはここでクラスを使用させません。たとえば、次のように
class MyClass : Hashable { }
class Foo<T: Hashable> { }
class SubFoo<T: MyClass> : Foo<T> { }
スウィフトは不思議な「T」の私たちがそれを作るために必要なコードを追加しても、「ハッシュ可能」(に準拠していないと文句を言い
最後に、右を。最もスウィフトに適したアプローチは、「Hashable」から継承し、必要な機能を追加する新しいプロトコルを作成する予定です。
サブクラスでString
を受け入れることは厳密には重要ではありません。それは、私たちのサブクラスには、実行中の作業に必要なメソッドとプロパティがあります。
これはそうではありません。これに関する迅速な問題/制限があります。http://stackoverflow.com/questions/24138359/limitation-with-classes-derived-from-generic-classes-in-swift – Ixx
@lxx:Ickを参照してください。私はそれがまだ*原因*だと思っていますが、あなたは別の解決策が必要です。試してみる可能性のある解決法で私の答えを編集しました。 –
さて、はい、捨て型のパラメータを持つソリューションは動作しますが、醜いので試していませんでした。反対側で、私はもう一度typealiasソリューションを試して、今すぐ動作します。 (選択された答え)は、文字列、パラメータを使用しようとしたが、エラーを引き起こしていた理由は、プレースホルダとしてIntを使用するため、問題がありました。私はそれをTと置き換えて、コンパイルするのではなく、クラスタブルを宣言しました。それはまだ解決策です。とにかく私に正しい解決策を教えてくれてありがとうと思っています:) – Ixx