Paulo Cesar
Paulo Cesar

Reputation: 2268

AnyObject vs. Struct (Any)

I would like to create a method like this for my projects:

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

    //...
}

But I can't because CGRect and CGSize are structs and do not conform to the AnyObject protocol. So, any ideas on how this could be done?

Upvotes: 8

Views: 5579

Answers (4)

ABakerSmith
ABakerSmith

Reputation: 22939

If you just need to print a CGRect or CGSize, you could use:

println(rect)

or

println(size)

You left a '...' at the end of your function so I assume there are more types that you need to print. To do that you need to make those types conform to the Printable protocol (unless they already do). Here's an example of how -

class Car { 
    var mileage = 0
}

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

The you can use:

let myCar = Car()
println(myCar)

Also, you may want to change the format of the way a type is currently printed. For example, if you wanted println(aRect) in the same format as returned by NSStringFromCGRect you could use the extension:

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

Upvotes: 1

Paulo Cesar
Paulo Cesar

Reputation: 2268

Just discovered a much better method of doing this. Swift has a method called dump, and it works with a lot of kinds of data.

For example:

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

Will print:

{x 0 y 5 w 30 h 60}

Upvotes: 2

Airspeed Velocity
Airspeed Velocity

Reputation: 40965

@nkukushkin's answer is correct, however, if what you want is a function that behaves differently depending on whether it’s passed a CGRect or a CGStruct, you are better off with overloading:

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

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

In comparison, the Any will be both inefficient (converting your structs to Any and back, could have a big impact if you do this a lot in a tight loop), and non-typesafe (you can pass anything into that function, and it will only fail at runtime).

If your intention is to coerce both types into a common type and then do the same operation on it, you can create a 3rd overload that takes that type, and have the other two call it.

Upvotes: 6

Nikita Kukushkin
Nikita Kukushkin

Reputation: 15138

Use Any instead of AnyObject.

Swift provides two special type aliases for working with non-specific types:

AnyObject can represent an instance of any class type.
Any can represent an instance of any type at all, including function types.

The Swift Programming Language

Upvotes: 11

Related Questions