Swift 2 (Xcode 7b4) で動作すると思われるコードをいくつか書きましたが、コンパイルされていません。私がやろうとしていることが有効であるかどうかについて、いくつかの考えを得たいと思っています。
Array
次の拡張例を検討してください。
extension Array where Element: AnyObject {
mutating func appendUniqueInstance(e: Element) {
for element in self {
if (element === e) {
return
}
}
self.append(e)
}
}
まず、要素が である配列とはどういう意味AnyObject
ですか? 基本的に、配列には、インスタンスの等価性 ( ) を比較できる非値型オブジェクトの異種グループを含める必要があると言っています===
。
例の関数appendUniqueInstance()
は、要素がまだ配列にない場合にのみ、要素を配列に挿入します。これは操作に似ていますが、明らかに順序付けを提供し、(さらに重要なことに)の同種型要件をSet
insert()
課しません(の の使用による)。Set
Equatable
Self
を実装するプロトコルP
とクラスを定義すると、次のようになります。C
P
protocol P : AnyObject {}
class C : P {}
をインスタンス化しますC
:
let c = C()
次に、これらの非常に明白なことが真実です。
let cIsAnyObject = c as AnyObject // ok
let cIsP = c as P // ok
そして、次のことができるようになりました。
var a1 = [AnyObject]() // []
a1.appendUniqueInstance(c) // [c]
a1.appendUniqueInstance(c) // [c]
ここまでは順調ですが、問題のケースについては次のとおりです。
var a2 = [P]()
a2.append(c) // ok, -> [c]
// Compiler error: Cannot invoke 'appendUniqueInstance' with an argument list of type '(C)'
a2.appendUniqueInstance(c)
ここで、a2
は の配列として型付けされているため、 のインスタンスP
に対して行うことは完全に有効なはずであり、実際に行は期待どおりに機能します。append
P
a2.append(c)
Array
ただし、拡張関数を呼び出すとappendUniqueInstance()
、コンパイラ エラーが発生します。
私が知る限り、コンパイラは何に渡すことができるかについて混乱しているようappendUniqueInstance()
で、C
(via P
) がAnyObject
.
P
ちなみに、代わりに次のように宣言すると:
@objc protocol P : AnyObject {}
その後、すべてが正常にコンパイルされますが、プロトコルのすべてが にP
準拠していることも確認する必要があります@objc
。これは私が望んでいるものではありません。
結局のところ、私の質問は次のとおりです。これはうまくいくように見えますか? 宣言の構文が間違っているだけではないことを願っていますが、そうであればうれしいと思います。