Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a generic class without the type argument in Swift?

I want to encapsulate a generic object in another class without setting the generic type argument. I created a base Animal<T> class and defined other subclasses from it. Example:

public class Animal<T: YummyObject> {
    // Code
}

public class Dog: Animal<Bark> {
    // Code
}

public class Cat: Animal<Meow> {
    // Code
}

and defined an Animal property, without the type argument, in the UITableView extension bellow:

extension UITableView {
    private static var animal: Animal!

    func addAnimal(animal: Animal) {
        UITableView.animal = animal
    }
}

but I get the following compile error when doing so:

Reference to generic type Animal requires arguments in <...>.

This seems to work fine in Java. How can I accomplish the same thing in Swift as well?

like image 890
ImanX Avatar asked Sep 30 '17 01:09

ImanX


People also ask

Which types can be used as arguments of a generic type?

The actual type arguments of a generic type are. reference types, wildcards, or. parameterized types (i.e. instantiations of other generic types).

Can generic class have non generic method?

Yes, you can define a generic method in a non-generic class in Java.

Can a generic class definition can only have one type parameter?

A class definition can have more than one type parameter.


1 Answers

Swift doesn’t yet support wildcard-style generics like Java does (i.e., Animal<?>). As such, a common pattern is to define a type-erased superclass, protocol (or wrapper) to enable such usage instead. For instance:

public class AnyAnimal {
    /* non-generic methods */
}

and then use it as your superclass:

public class Animal<T: YummyObject>: AnyAnimal {
    ...
}

Finally, use AnyAnimal in your non-generic code instead:

private static var animal: AnyAnimal!

Examples in the Swift Standard Library. For a practical example, see the KeyPath, PartialKeyPath, and AnyKeyPath classes hierarchy. They follow the same pattern I outlined above. The Collections framework provides even further type-erasing examples, but using wrappers instead.

like image 75
Paulo Mattos Avatar answered Oct 31 '22 18:10

Paulo Mattos