I have this question except for Swift. How do I use a Type
variable in a generic?
I tried this:
func intType() -> Int.Type { return Int.self } func test() { var t = self.intType() var arr = Array<t>() // Error: "'t' is not a type". Uh... yeah, it is. }
This didn't work either:
var arr = Array<t.Type>() // Error: "'t' is not a type" var arr = Array<t.self>() // Swift doesn't seem to even understand this syntax at all.
Is there a way to do this? I get the feeling that Swift just doesn't support it and is giving me somewhat ambiguous error messages.
Edit: Here's a more complex example where the problem can't be circumvented using a generic function header. Of course it doesn't make sense, but I have a sensible use for this kind of functionality somewhere in my code and would rather post a clean example instead of my actual code:
func someTypes() -> [Any.Type] { var ret = [Any.Type]() for (var i = 0; i<rand()%10; i++) { if (rand()%2 == 0){ ret.append(Int.self) } else {ret.append(String.self) } } return ret } func test() { var ts = self.someTypes() for t in ts { var arr = Array<t>() } }
Yes it is possible, but only for Functions, not any arbitrary variable. As you can see, it's the type itself, where you define generics and then you can make a variable of that type, which allows it to set the generic.
Generics in Java is similar to templates in C++. The idea is to allow type (Integer, String, … etc and user defined types) to be a parameter to methods, classes and interfaces. For example, classes like HashSet, ArrayList, HashMap, etc use generics very well. We can use them for any type.
It specifies the type parameters (also called type variables) T1, T2, ..., and Tn. To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public class Box<T>". This introduces the type variable, T, that can be used anywhere inside the class.
Not really. You need to use reflection, basically. Generics are really aimed at static typing rather than types only known at execution time.
Swift's static typing means the type of a variable must be known at compile time.
In the context of a generic function func foo<T>() { ... }
, T looks like a variable, but its type is actually known at compile time based on where the function is called from. The behavior of Array<T>()
depends on T
, but this information is known at compile time.
When using protocols, Swift employs dynamic dispatch, so you can write Array<MyProtocol>()
, and the array simply stores references to things which implement MyProtocol
— so when you get something out of the array, you have access to all functions/variables/typealiases required by MyProtocol
.
But if t
is actually a variable of kind Any.Type
, Array<t>()
is meaningless since its type is actually not known at compile time. (Since Array
is a generic struct, the compiler needs know which type to use as the generic parameter, but this is not possible.)
I would recommend watching some videos from WWDC this year:
I found this slide particularly helpful for understanding protocols and dynamic dispatch:
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