Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Swift generics to pass a type and return an object as that type?

I'm writing a function that, given a type, simply unarchives an object from the disk and returns it as that type. This is what it looks like:

public class func objectWithFileName<T>(fileName: String, inFolder folder: NSSearchPathDirectory) -> T? {
    // Build an NSURL var called fileURL based on the fileName and folder.
    // ...

    // If any object was found
    if let object: AnyObject = NSKeyedUnarchiver.unarchiveObjectWithFile(fileURL.path!) {
        // Attempt to return the object as an object of type T.
        if let typedObject = object as? T {
            return typedObject
        }
    }
    return nil
}

The planned way of consuming the function is this, and it doesn't work (I'm getting "Cannot specialize a non-generic definition"):

if let user = MQFileManager.objectWithFileName<User>("User", inFolder: .DocumentDirectory) {

}

How can I pull this off correctly?

like image 582
MLQ Avatar asked Apr 16 '15 12:04

MLQ


People also ask

How do I use generics in Swift?

The generic version of the function uses a placeholder type name (called T , in this case) instead of an actual type name (such as Int , String , or Double ). The placeholder type name doesn't say anything about what T must be, but it does say that both a and b must be of the same type T , whatever T represents.

What is generic type argument?

The generic argument list is a comma-separated list of type arguments. A type argument is the name of an actual concrete type that replaces a corresponding type parameter in the generic parameter clause of a generic type. The result is a specialized version of that generic type.

What are generics How do you make a method or variable generics 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 specify the type of the variable the return value is assigned to, type inference can do the rest. So if you have a User type, simply invoke the function as follows:

if let user: User = MQFileManager.objectWithFileName("User", inFolder: .DocumentDirectory) {

}

Since the user variable is of User type, the compiler can infer the T generic to be of User type

like image 122
Antonio Avatar answered Sep 28 '22 02:09

Antonio