2015-04-01 5 views
8

Я хотел бы создать метод, как это для моих проектов:AnyObject против Struct (Любой)

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

    //... 
} 

Но я не могу, потому что CGRect и CGSize являются struct s и не соответствуют AnyObject , Итак, какие-либо идеи о том, как это можно сделать?

ответ

5

@ ответ nkukushkin является правильным, однако, если то, что вы хотите, это функция, которая ведет себя по-разному в зависимости от того, где принят CGRect или CGStruct, вы лучше с перегрузкой:

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

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

Для сравнения: Any будет неэффективным (преобразование ваших структур в Any и обратно, может иметь большое значение, если вы сделаете это много в плотном цикле), и не-typeafe (y ou может передать что-либо в эту функцию, и она будет работать только во время выполнения).

Если вы намерены объединить оба типа в общий тип, а затем выполнить ту же операцию на нем, вы можете создать третью перегрузку, которая принимает этот тип, и две другие вызовут ее.

+0

Это очень хорошо. По какой-то причине я полностью забыл о перегрузке метода. –

9

Использовать Any вместо AnyObject.

Swift предоставляет два специальных псевдонимов типа для работы с неспецифическими типов:

AnyObject может представлять собой экземпляр любого типа класса.
Any может представлять экземпляр любого типа вообще, включая типы функций.

The Swift Programming Language

2

Только что нашел намного лучший способ сделать это. У Swift есть метод, называемый дамп, и он работает с множеством видов данных.

Например:

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

Напечатает:

{x 0 y 5 w 30 h 60} 
1

Если вам просто нужно напечатать CGRect или CGSize, вы можете использовать:

println(rect) 

или

println(size) 

Вы оставили «...» в конце своей функции, поэтому я предполагаю, что существует больше типов, которые нужно распечатать. Для этого вам необходимо, чтобы эти типы соответствовали протоколу Printable (если они уже не выполняются).Вот пример того, как -

class Car { 
    var mileage = 0 
} 

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

вы можете использовать:

let myCar = Car() 
println(myCar) 

Кроме того, вы можете изменить формат пути типа в настоящее время печати. Например, если вы хотите println(aRect) в том же формате, возвращаемый NSStringFromCGRect вы можете использовать расширение:

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

Да, это правда. Но я думаю, что «дамп» и «NSStringFromCGRect» создают формат, который легче читать. Ты знаешь почему? –

+0

Вы используете игровые площадки для тестирования своего кода? Я считаю, что ваш код 'dump (CGRectMake (0, 5, 30, 60))' на самом деле просто показывает вам предварительный просмотр 'CGRect' на игровой площадке. Попробуйте код 'let rect = CGRect (x: 0, y: 5, ширина: 30, высота: 60); dump (rect) ', и вы должны получить тот же формат, что и' println (rect) '. – ABakerSmith

+0

Я обновил свой ответ, чтобы поговорить о том, как вы могли изменить формат при использовании 'println'. – ABakerSmith