Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it necessary to pass a type parameter to static functions in a generic class?

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:

  1. give GenericClass a type argument -- doesn't matter which type:

    let y: Int = GenericClass<Void>.blub(4)
    
  2. 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:

enter image description here

like image 483
Matt Fenwick Avatar asked Aug 15 '16 21:08

Matt Fenwick


People also ask

Does a generic method have to be static?

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.

Can a method that uses a generic class parameter be static Why?

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.

Are static fields of type parameters allowed?

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.

What is the difference between generic class and generic method?

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.


1 Answers

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.

like image 189
Rob Napier Avatar answered Oct 22 '22 11:10

Rob Napier