2015-04-01 18 views
8

Chciałbym utworzyć metodę takiego dla moich projektów:AnyObject vs Struct (Każdy)

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

    //... 
} 

Ale nie mogę, bo i CGSizeCGRectstruct s są i nie są zgodne z AnyObject . Jakieś pomysły na to, jak można to zrobić?

Odpowiedz

5

@ odpowiedź nkukushkin jest poprawne, jednak, jeśli to, co chcesz to funkcja, która zachowuje się różnie w zależności od tego, czy podjęła CGRect lub CGStruct, jesteś lepiej z przeciążeniem:

func print(rect: CGRect) { 
    println(NSStringFromCGRect(rect)) 
} 

func print(size: CGSize) { 
    println(NSStringFromCGSize(size)) 
} 

W porównaniu, Any będzie zarówno nieefektywne (konwersja twoich struktur do Any iz powrotem, może mieć duży wpływ, jeśli zrobisz to dużo w ciasnej pętli), i nie-bez ochrony (y możesz przekazać cokolwiek do tej funkcji, a to się nie powiedzie w czasie wykonywania).

Jeśli masz zamiar zmusić oba typy do wspólnego typu, a następnie wykonać na nim tę samą operację, możesz utworzyć trzecie przeciążenie, które będzie tego typu, a pozostałe dwa wywołają.

+0

To bardzo dobry. Z jakiegoś powodu zupełnie zapomniałem o przeciążeniu metody. –

9

Użyj Any zamiast AnyObject.

Swift oferuje dwa specjalne aliasy typu pracy z niespecyficznych typów:

AnyObject może oznaczać wystąpienie dowolnego typu klasy.
Any może reprezentować dowolne wystąpienie dowolnego typu, w tym typy funkcji.

The Swift Programming Language

2

Właśnie odkryłem znacznie lepszą metodę robienia tego. Swift ma metodę o nazwie dump i działa z wieloma rodzajami danych.

Na przykład:

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

wypisze:

{x 0 y 5 w 30 h 60} 
1

Jeśli wystarczy wydrukować CGRect lub CGSize, można użyć:

println(rect) 

lub

println(size) 

Zostawiłeś "..." na końcu swojej funkcji, więc zakładam, że jest więcej typów, które musisz wydrukować. Aby to zrobić, musisz dostosować te typy do protokołu Printable (chyba, że ​​już to robią).Oto przykład, w jaki sposób -

class Car { 
    var mileage = 0 
} 

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

można użyć:

let myCar = Car() 
println(myCar) 

Również może chcesz zmienić format drodze typu jest aktualnie drukowanej. Na przykład, jeśli chcesz println(aRect) w takim samym formacie jak zwrócony przez NSStringFromCGRect można użyć rozszerzenia:

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

Tak, to prawda. Ale myślę, że "dump" i "NSStringFromCGRect" tworzy format, który jest łatwiejszy do odczytania. Wiesz dlaczego? –

+0

Czy używasz Placów zabaw do testowania kodu? Wierzę, że twój kod 'dump (CGRectMake (0, 5, 30, 60)) właśnie pokazuje ci podgląd' CGRect' przy placu zabaw. Wypróbuj kod 'let rect = CGRect (x: 0, y: 5, szerokość: 30, wysokość: 60); dump (rect) 'i powinieneś otrzymać ten sam format co' println (rect) '. – ABakerSmith

+0

Zaktualizowałem swoją odpowiedź, aby porozmawiać o tym, jak można zmienić format podczas używania 'println'. – ABakerSmith

Powiązane problemy