2016-09-19 4 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' 메소드를 추가 할 것이고, Asker는이 메소드를 클래스를 포함하는 배열로만 제한하려고합니다. – 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