/// The protocol to which all types implicitly conform.
public typealias Any = protocol<>
Any
ist nur ein Protokoll, das alle Typen implizit entsprechen - es ist kein konkreter selbst. Swift kann nicht eine Reihe von Nicht-Beton-Typen ableiten, weshalb es nicht Any
zu schließen, aber mit NSObject
erfolgreich ist (Int
-NSNumber
überbrückt werden kann, kann String
-NSString
überbrückt werden - und sie erben beide von NSObject
, das ist ein Beton Art).
Betrachten wir zum Beispiel diese:
protocol Foo {}
struct Bar:Foo {}
struct Baz:Foo {}
let arr = [Bar(), Baz()] // error: Type of expression is ambiguous without more context
Da Foo
ein nicht-Beton-Typ ist, Swift kann eine Reihe von nicht schließen. Sie müssen explizit den Compiler sagen, was Sie ihrer Art sein wollen:
let arr:[Foo] = [Bar(), Baz()]
Sie werden auch das gleiche Verhalten mit AnyObject
erhalten (wie es ein Protokoll ist, dass alle Klassen implizit entsprechen - aber noch kein Beton-Typ):
class Qux {}
class Fox {}
let a = [Qux(), Fox()] // error: Type of expression is ambiguous without more context
let a1:[AnyObject] = [Qux(), Fox()] // no error
Warum Swift ist nicht in der Lage eine Reihe von nicht-Betone zu schließen ist höchstwahrscheinlich aufgrund der bestehenden Grenzen der nicht-Betone in der Sprache - zur Zeit Betont erforderlich sind für die meisten nicht-triviale Operationen. See this great Q&A for an example.
Aber um ehrlich zu sein, sollten Sie wirklich mehr darüber nachdenken, ob Sie tatsächlich brauchen ein Array von Any
. Ich kann mir keine einzige praktische Anwendung eines Arrays von Any
vorstellen, da alles, was implizit mit den Elementen übereinstimmt, garantiert nichts tun muss (Sie können keine bestimmte Methode für etwas nennen, das irgendwas sein könnte). Natürlich kannst du auch schreiben, aber was bringt es, die Typsicherheit zurückzubekommen, die du zuerst weggeworfen hast?
Sie sollten immer so typspezifisch wie möglich sein. Sie könnten einen Wrapper für Ihre Werte erstellen - dies könnte entweder ein einfaches struct
sein, um ein paar Eigenschaften zu umbrechen, oder ein type erasure, um nicht konkrete Typen in einen pseudo-konkreten Typ einzubinden. Zumindest sollten Sie in Erwägung ziehen, ein eigenes Protokoll zu erstellen, dem Ihre Array-Elemente entsprechen.
Die letzten zwei Absätze heben hier die wichtigsten Punkte hervor. Und ehrlich gesagt, 'NSObject' (oder' AnyObject', das hier nicht funktionieren würde, aber ich sehe es die ganze Zeit verwendet) ist nicht viel spezifischer als 'Any'. – nhgrif
@ originaluser2 Ihre Erklärung ist wirklich hilfreich, vielen Dank – c41ux
@ c41ux Glücklich zu helfen :) – Hamish