Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Swift function to test for object type

I'm trying to write a function that takes an object and a type as arguments and returns a boolean indicating whether or not the object is of the given type. There doesn't seem to be a Type type, so I'm not sure how to do this. The best I've been able to do is

func objectIsType<T>(object: AnyObject, someObjectOfType: T) -> Bool {
    return object is T
}

So I can do objectIsType(x, 5), to test if x is an Int or objectIsType(x, "hi") to see if it's a string, but I'd like to be able to call objectIsType(x, Int) to see if x is an Int and objectIsType(x, String) to see if it's a String. Is something like this possible?

Edit:

Airspeed Velocity improved my function and made a great point about it doing exactly what is already does. The new function is this:

func objectIsType<T>(object: Any, someObjectOfType: T.Type) -> Bool {
    return object is T
}

What I'm trying to do is to validate that the values of a [String: Any] dictionary are of the type that I expect. For instance:

let validator: [String: Any.Type] = [
    "gimme an int": Int.self,
    "this better be a string": String.self
]

let validatee: [String: Any] = [
    "gimme an int": 3,
    "this better be a string": "it is!"
]

for (key, type) in validator {
    if !objectIsType(validatee[key], type) {
        selfDestruct()
    }
}

But I'm getting the error, <>protocol.Type is not convertible to T.type. I've looked at the Metatype documentation, but I'm still a bit confused.

like image 834
mway Avatar asked Mar 12 '15 16:03

mway


People also ask

How do you write a generic function in Swift?

Swift Generic Function In Swift, we can create a function that can be used with any type of data. Such a function is known as a Generic Function. Here's how we can create a generic function in Swift: // create a generic function func displayData<T>(data: T){ ... }

Which of the following are generic types in Swift?

Swift 4 language provides 'Generic' features to write flexible and reusable functions and types. Generics are used to avoid duplication and to provide abstraction. Swift 4 standard libraries are built with generics code. Swift 4s 'Arrays' and 'Dictionary' types belong to generic collections.

What is generic protocol in Swift?

Swift enables us to create generic types, protocols, and functions, that aren't tied to any specific concrete type — but can instead be used with any type that meets a given set of requirements.

How do you define a generic variable in Swift?

Generics allow you to declare a variable which, on execution, may be assigned to a set of types defined by us. In Swift, an array can hold data of any type. If we need an array of integers, strings, or floats, we can create one with the Swift standard library.


1 Answers

If you want to supply a type as the argument, not a value, you can do the following:

func objectIsType<T>(object: Any, someObjectOfType: T.Type) -> Bool {
    return object is T
}

let a: Any = 1

objectIsType(a, Int.self)  // returns true

NB, AnyObject can only refer to classes, not structs or enums. Int and String are structs. If you change your code, as I have above, to take an Any, it works with structs too.

It might have seemed like your original worked without this change, but really what was happening was the interop was converting your Int into an NSNumber which is a bit of a roundabout way of doing things and won't adapt to the metatype-based approach.

But the question really is, why do you think you need this? is already does exactly this.

like image 116
Airspeed Velocity Avatar answered Oct 20 '22 01:10

Airspeed Velocity