2016-09-19 3 views
2

私は次のことを達成したいと思います。任意のインスタンスを配列から削除することができます。しかし、以下は有効なSwift 3の構文ではありません:スウィフトジェネリックはクラスインスタンスを配列から削除します

extension Array where Element: class { // error: Expected identifier for type name 
    mutating func remove(_ object: AnyObject) { 
     if let index = index(where: { $0 === object }) { 
      remove(at: index) 
     } 
    } 
} 

protocol MyProtocol: class { } 
class MyClass: MyProtocol { } 
var myInstance = MyClass() 
var myArray: [MyProtocol] = [myInstance] 
myArray.remove(myInstance) 

一般的なアプローチはどのように機能しますか? MyProtocolやEquatableのジェネリック拡張を特別な場合はしたくありません。

答えて

2

これによって拡張機能を置き換えます。

extension Array { // error: Expected identifier for type name 
    mutating func remove(_ object: AnyObject) { 
     if let index = index(where: { $0 as AnyObject === object }) { 
      remove(at: index) 
     } 
    } 
} 
+1

これはすべての 'Array'インスタンスに' remove'メソッドを追加します。アスカーはこのメソッドをクラスを含む配列に制限したいと思うと思います。 – Cristik

3

AnyObject代わりのclass:にあなたの制約を変換します

extension Array where Element: AnyObject { 
    mutating func remove2(_ object: AnyObject) { 
     if let index = index(where: { $0 === object }) { 
      remove(at: index) 
     } 
    } 
} 

ドキュメントに基づいて、AnyObject

The protocol to which all classes implicitly conform.

だけです問題はコンパイラがそれは次のようにスローされますよう、あなたが、var myArray: [MyProtocol]を宣言してみましょう:

error: using 'MyProtocol' as a concrete type conforming to protocol 'AnyObject' is not supported

ですから、var myArray: [AnyObject]する必要があります。 Hereは、この制限が現在Swiftに存在する理由の良い説明です。

+0

ご返信ありがとうございます。私があなたの回答から理解していることは、現在、型付きオブジェクトやコレクションでこれを行う方法がないということです。コンパイラは配列をそのように書くことができますが、[AnyObject]として宣言されていない限り、removeメソッドを見ることはできません。 – bouke

+0

はい。 'AnyObject'の配列を宣言することは許されていますが、' AnyObject'から派生したプロトコルの配列を宣言することは許されていません。おそらく、コンパイラが 'AnyObject'に対して優遇措置を取っているからです。 – Cristik

関連する問題