2015-04-01 21 views
8

Vorrei creare un metodo come questo per i miei progetti:ANYOBJECT vs. Struct (Qualsiasi)

func print(obj: AnyObject) { 
    if let rect = obj as? CGRect { 
     println(NSStringFromCGRect(rect)) 
    } 
    else if let size = obj as? CGSize { 
     println(NSStringFromCGSize(size)) 
    } 

    //... 
} 

Ma non posso perché CGRect e CGSize sono struct s e non conforme alla AnyObject . Quindi, qualche idea su come questo potrebbe essere fatto?

risposta

5

@ risposta di nkukushkin è corretta, tuttavia, se quello che vuoi è una funzione che si comporta in modo diverso a seconda che si tratti di approvato una CGRect o un CGStruct, si sta meglio con sovraccarico:

In confronto, lo Any sarà sia inefficiente (conversione delle strutture in Any e ritorno, potrebbe avere un grosso impatto se lo si fa molto in un ciclo stretto), e non tipicamente (y ou può passare qualsiasi cosa in quella funzione, e fallirà solo in fase di esecuzione).

Se l'intenzione è di forzare entrambi i tipi in un tipo comune e quindi eseguire la stessa operazione su di esso, è possibile creare un terzo sovraccarico che riprenda quel tipo e che gli altri due lo chiamino.

+0

che è molto buona. Per qualche ragione ho completamente dimenticato il sovraccarico del metodo. –

9

Utilizzare Any anziché AnyObject.

Swift fornisce due tipo speciale alias per lavorare con non specifici tipi:

AnyObject può rappresentare un'istanza di qualsiasi tipo di classe.
Any può rappresentare un'istanza di qualsiasi tipo, compresi i tipi di funzione.

The Swift Programming Language

2

Ho appena scoperto un metodo molto migliore per farlo. Swift ha un metodo chiamato discarica e funziona con molti tipi di dati.

Ad esempio:

dump(CGRectMake(0, 5, 30, 60)) 

stamperà:

{x 0 y 5 w 30 h 60} 
1

Se avete solo bisogno di stampare un CGRect o CGSize, è possibile utilizzare:

println(rect) 

o

println(size) 

Hai lasciato un '...' alla fine della tua funzione quindi presumo che ci siano più tipi che devi stampare. Per fare questo è necessario rendere tali tipi conformi al protocollo Printable (a meno che non lo facciano già).Ecco un esempio di come -

class Car { 
    var mileage = 0 
} 

extension Car : Printable { 
    var description: String { 
     return "A car that has travelled \(mileage) miles." 
    } 
} 

La si può usare:

let myCar = Car() 
println(myCar) 

Inoltre, si consiglia di cambiare il formato del modo in cui un tipo è attualmente stampata. Ad esempio, se si voleva println(aRect) nello stesso formato come restituito da NSStringFromCGRect si potrebbe usare l'estensione:

extension CGRect : Printable { 
    public var description: String { 
     return "{\(origin.x), \(origin.y)}, {\(size.width), \(size.height)}" 
    } 
} 
+0

Sì, è vero. Ma penso che "dump" e "NSStringFromCGRect" producano un formato che è più facile da leggere. Sai perché? –

+0

Stai usando Playgrounds per testare il tuo codice? Credo che il tuo 'dump del codice '(CGRectMake (0, 5, 30, 60))' in realtà ti stia solo mostrando un'anteprima del 'CGRect' nel parco giochi. Prova il codice 'lascia rect = CGRect (x: 0, y: 5, larghezza: 30, altezza: 60); dump (rect) 'e dovresti ottenere lo stesso formato di' println (rect) '. – ABakerSmith

+0

Ho aggiornato la mia risposta per parlare di come è possibile modificare il formato quando si utilizza 'println'. – ABakerSmith