My class: my class takes one type parameter, and has one static method which does not use the type parameter:
class GenericClass<T> {
static func blub(x: Int) -> Int {
return x + 1
}
}
My problem: when I attempt to use the static function, my code does not compile:
let z: Int = GenericClass.blub(4) // doesn't compile
I've come up with two workarounds:
give GenericClass
a type argument -- doesn't matter which type:
let y: Int = GenericClass<Void>.blub(4)
create a second class, which doesn't have any type parameters, to hold the static methods
So I know how to get the code working, although it may not be the optimal solution. But my question is about why Swift works this way.
My question:
Why doesn't let y: Int = GenericClass.blub(4)
compile?
It should compile because blub
is a static method and therefore shouldn't have any interaction with the type parameters, which are only used for instances, not for static methods and variables. Or at least, that's what I expected.
Where am I wrong? How do class-level type parameters and static methods interact in Swift?
Is there a better way to solve this problem than the two workarounds I tried?
Screenshot:
Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.
1 Answer. You can't use a class's generic type parameters in static methods or static fields. The class's type parameters are only in scope for instance methods and instance fields.
A class's static field is a class-level variable shared by all non-static objects of the class. Hence, static fields of type parameters are not allowed.
A generic class or structure can contain nongeneric procedures, and a nongeneric class, structure, or module can contain generic procedures. A generic procedure can use its type parameters in its normal parameter list, in its return type if it has one, and in its procedure code.
GenericClass
is not a concrete type in Swift. There's no way to talk about it any more than you can talk about the type Array
without providing its type parameter. (The specific feature Swift lacks that would allow this is called "higher-kinded types.")
Static methods are tied to the concrete type (GenericClass<T>
) not to the higher-kinded type (GenericClass
). In order to access the static methods, it needs to know the actual type you want.
While it's true you're not currently using the type parameter in this class method, there is nothing stopping you (or a subclass!) from doing so. Since you have no way to promise that T
will never occur in this method, there's no way for Swift to allow you to ignore it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With