2016-09-19 2 views
2

Ich möchte folgendes erreichen; in der Lage sein, jede gegebene Instanz aus einem Array zu entfernen. Folgendes ist jedoch nicht gültig Swift 3 Syntax:Swift generische Klasseninstanz vom Array entfernen

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) 

Wie würde ein generischer Ansatz funktionieren? Ich möchte nicht die generische Erweiterung auf MyProtocol oder Equatable spezialisieren.

Antwort

2

durch diese die Erweiterung ersetzen:

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

Dies wird die Methode 'remove' zu ​​allen' Array'-Instanzen hinzufügen, und ich denke, der Fragesteller möchte diese Methode nur auf Arrays beschränken, die Klassen enthalten. – Cristik

3

zu AnyObject statt class: Konvertieren Sie Ihre Einschränkung:

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

wie auf der Dokumentation basiert, AnyObject

die einzige

The protocol to which all classes implicitly conform.

ist Problem ist jetzt, dass der Compiler nicht können Sie erklären var myArray: [MyProtocol], wie es folgendes werfen:

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

So müssen Sie var myArray: [AnyObject]. Here ist eine gute Erklärung dafür, warum diese Einschränkung derzeit in Swift existiert.

+0

Danke für Ihre Antwort. Aus dem was ich von Ihrer Antwort verstehe ist, dass es derzeit keine Möglichkeit gibt, dies mit typisierten Objekten und Sammlungen zu erreichen. Der Compiler erlaubt mir, das Array auf diese Weise zu schreiben, aber es kann die Methode remove nicht sehen, wenn es nicht als [AnyObject] deklariert ist. – bouke

+0

Ja. Es ist seltsam, dass Sie ein Array von AnyObject deklarieren dürfen, aber Sie dürfen kein Array eines von AnyObject abgeleiteten Protokolls deklarieren. Vielleicht liegt das daran, dass der Compiler "AnyObject" bevorzugt behandelt. – Cristik