2014-06-16 14 views
10

In Swift Programming Language, si dice "Un array memorizza più valori dello stesso tipo in una lista ordinata". Ma ho scoperto che è possibile memorizzare più tipi di valori nella matrice. La descrizione è errata?Archiviazione di diversi tipi di valori in Array in Swift

ad es.

var test = ["a", "b", true, "hi", 1] 

risposta

17

Da REPL

xcrun swift 
    1> import Foundation 
    2> var test = ["a", "b", true, "hi", 1] 
test: __NSArrayI = @"5 objects" { 
    [0] = "a" 
    [1] = "b" 
    [2] = 
    [3] = "hi" 
    [4] = (long)1 
} 
    3> 

potete vedere test è NSArray, che è una specie di AnyObject[] o NSObject[]

Cosa succede è che Foundation fornisce la capacità di convertire il numero e boolean in NSNumber. Il compilatore eseguirà la conversione ogni volta che è necessario per compilare il codice.

Così ora hanno tipo comune di NSObject e quindi dedurre come NSArray


Il codice non viene compilato in REPL senza import Foundation.

var test = ["a", "b", true, "hi", 1] 
<REPL>:1:12: error: cannot convert the expression's type 'Array' to type 'ArrayLiteralConvertible' 

var test:Array = ["a", "b", true, "hi", 1] 
<REPL>:4:18: error: cannot convert the expression's type 'Array' to type 'ExtendedGraphemeClusterLiteralConvertible' 

ma si può fare questo

var test : Any[] = ["a", "b", true, "hi", 1] 

Perché hanno un tipo comune, che è Any.


Nota: AnyObject[] non funziona senza import Foundation.

var test:AnyObject[] = ["a", "b", true, "hi", 1] 
<REPL>:2:24: error: type 'Bool' does not conform to protocol 'AnyObject' 
+0

Intendi ANYOBJECT? – Boon

+0

AnyObject è il tipo – juniperi

+0

Esiste un modo per verificare il tipo inferito di un array? – Boon

1

La descrizione è corretta, una matrice memorizza più valori dello stesso tipo. La chiave è che un valore ha più tipi. Ad esempio, uno String ha tipi di String e Any; un'istanza di una classe Ellipse : Shape ha tipi di Ellipse, Shape, AnyObject e Any.

14> class Foo {} 
15> class Bar : Foo {} 
16> var ar1 : Array<Any> = [1, "abc", Foo(), Bar()] 
ar1: Any[] = size=4 { 
    [0] = <read memory from 0x7fa68a4e67b0 failed (0 of 8 bytes read)> 
    [1] = { ... } 
    [2] = {} 
    [3] = { ... } 
} 
17> ar1[0] 
$R5: Int = <read memory from 0x7fa68a51e3c0 failed (0 of 8 bytes read)> 
18> ar1[1] 
$R6: String = { ... } 
19> ar1[2] 
$R7: Foo = {} 
20> ar1[3] 
$R8: Bar = { 
    lldb_expr_14.Foo = {} 
} 
21> ar1[0] as Int 
$R9: Int = 1 
2

AnyObject è un tipo e si può creare una matrice che contiene quelli, che (come dice il nome della classe) significa che può contenere qualsiasi tipo di oggetto. Gli NSArrays non sono legati al tipo e quando si crea un array con tipi misti, verrà generato un NSArray anziché uno Array. Non mi affiderei a questo, tuttavia, poiché potrebbe cambiare in futuro (AnyObject [] viene automaticamente colato con NSArray).

Si può provare questo in un parco giochi (nota: dynamicType restituisce "(metatipo)" e non ero sicuro di come tirare fuori la realtà digitare così ho invocato l'errore del compilatore):

var x = [ 1, 2, "a" ] 
x.dynamicType.description() // -> __NSArrayI 

var y = [ 1, 2 ] 
y.dynamicType.description() // -> Error: Array<Int>.Type does not have a member named 'description'. 

var z: AnyObject[] = [ 1, 2, "a" ] 
z.dynamicType.description() // -> Error: Array<AnyObject>.Type does not have a member named 'description'. 
+0

Martin, non riesco a ottenere x.dynamicType.description() per compilare in Xcode. – Boon

+0

Grazie Martin, buona prova. – Boon

3

Per inizializzare una matrice con tipi arbitrari, basta usare var arbitraryArray = [Any]().

0

In Swift 3 è possibile utilizzare:

var testArray = ["a",true,3,"b"] as [Any]