Generics call with Type T in Swift

Prine

In my application I want to create an generic method which creates an array of object depening on the given type T.

I created the following function:

func getArray<T : ROJSONObject>(key:String) -> T[] {
    var elements = T[]()

    for jsonValue in getValue(key).array! {
        var element = T()

        element.jsonData = jsonValue
        elements.append(element)
    }

    return elements
}

Now I want to pass the type when I call the method, so it does know which type it should create internally. I think in Java and C# you can use a method like that:

object.getArray<Document>("key")

When I call it like that, I always get the error:

Cannot explicitly specialize a generic function

So my fix was to define an additional parameter containing an instance of the type T so it does automatically detect the type:

func getArray<T : ROJSONObject>(key:String, type:T) -> T[] {
    var elements = T[]()

    for jsonValue in getValue(key).array! {
        var element = T()

        element.jsonData = jsonValue
        elements.append(element)
    }

    return elements
}

Is there really no other way to get that behaviour without passing an unused instance? Or am I misunterstanding something?

Further Testing

After the answer of jtbandes I did some more testing. I tried to force the Type by adding the as in the call.

class Person {

    init() { }

    func getWorkingHours() -> Float {
        return 40.0
    }
}

class Boss : Person {
    override func getWorkingHours() -> Float {
        println(100.0)
        return 100.0
    }
}

class Worker : Person {
    override func getWorkingHours() -> Float {
        println(42.0)
        return 42.0
    }
}

func getWorkingHours<T : Person>() -> T {
    var person = T()
    person.getWorkingHours()

    return person
}

var worker:Worker = getWorkingHours() as Worker
var boss:Boss = getWorkingHours() as Boss
worker.getWorkingHours() // prints out 40.0 instead of 42.0
boss.getWorkingHours() // prints out 40.0 instead of 100.0

So somehow the type is always the base type even I've specified the type with the as keyword. I know the example does not make much sense, but it was just for testing purpose..

Bryan Chen

I think it is a bug.

You can work around it by making the class a sub-class of NSObject or mark constructor of base class with @required

import Cocoa

class A : NSObject {
    init() { }
}
class B : A {}
class C : A {}

func Create<T:NSObject> () -> T {
    return T()
}

println(Create() as A)
println(Create() as B)
println(Create() as C)

//<_TtC11lldb_expr_01A: 0x7f85ab717bc0>
//<_TtC11lldb_expr_01B: 0x7f85ab451e00>
//<_TtC11lldb_expr_01C: 0x7f85ab509160>

class D {
    @required init() { } 
}

class E : D {
    init() { }
}

class F : D {
    init() { }
}

func Create2<T:D> () -> T {
    return T()
}

println(Create2() as D)
println(Create2() as E)
println(Create2() as F)

//C11lldb_expr_01D (has 0 children)
//C11lldb_expr_01E (has 1 child)
//C11lldb_expr_01F (has 1 child)

Not sure why @required solve the problem. But this is the reference

required

Apply this attribute to a designated or convenience initializer of a class to indicate that every subclass must implement that initializer.

Required designated initializers must be implemented explicitly. Required convenience initializers can be either implemented explicitly or inherited when the subclass directly implements all of the superclass’s designated initializers (or when the subclass overrides the designated initializers with convenience initializers).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Swift Generics: function with T.Type as parameter returns optional T

From Dev

Swift generics not preserving type

From Dev

Type inference with Generics in Swift

From Dev

Apple Swift: Type Casting Generics

From Dev

Swift Generics Type Inference Extensions

From Dev

Swift Generics: where in type declaration

From Dev

Swift generics: return type based on parameter type

From Dev

array of type T (Java generics)

From Dev

Swift generics in protocol: operator '===' cannot be applied to operands of type '_' and 'Self.T'

From Dev

Swift generics: requiring addition and multiplication abilities of a type

From Dev

Swift require that two generics are of the same type

From Dev

Swift Generics equivalent of Java any type <?>

From Dev

Swift nested generics type does not conform to protocol

From Dev

Swift require that two generics are of the same type

From Dev

Java generics - type mismatch from T to T

From Dev

'Object' is not convertible to 'T' using Generics in Swift

From Dev

'Object' is not convertible to 'T' using Generics in Swift

From Dev

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

From Dev

Java generics, call T method as T and not as its superclass

From Dev

Subscript an Arrary of generics type: error: Cannot subscript a value of type '[T]'

From Dev

Can you have protocol extension for a specific generics type in Swift?

From Dev

Understanding swift generics vs treating parameters as a protocol or base type

From Dev

Can you have protocol extension for a specific generics type in Swift?

From Dev

Type Safety using Generics : Check T to Interface<T>

From Dev

Kotlin: Generics, reflection and the difference between type T and T:Any

From Dev

Mockito.any() to match any instance of generics type T

From Dev

Java Generics bounded type doesn't apply to method parameters

From Dev

(Generics)Cannot make a static reference to the non-static type T

From Dev

Java Generics Clarification( Constraining T to a type, while using Comparable)

Related Related

  1. 1

    Swift Generics: function with T.Type as parameter returns optional T

  2. 2

    Swift generics not preserving type

  3. 3

    Type inference with Generics in Swift

  4. 4

    Apple Swift: Type Casting Generics

  5. 5

    Swift Generics Type Inference Extensions

  6. 6

    Swift Generics: where in type declaration

  7. 7

    Swift generics: return type based on parameter type

  8. 8

    array of type T (Java generics)

  9. 9

    Swift generics in protocol: operator '===' cannot be applied to operands of type '_' and 'Self.T'

  10. 10

    Swift generics: requiring addition and multiplication abilities of a type

  11. 11

    Swift require that two generics are of the same type

  12. 12

    Swift Generics equivalent of Java any type <?>

  13. 13

    Swift nested generics type does not conform to protocol

  14. 14

    Swift require that two generics are of the same type

  15. 15

    Java generics - type mismatch from T to T

  16. 16

    'Object' is not convertible to 'T' using Generics in Swift

  17. 17

    'Object' is not convertible to 'T' using Generics in Swift

  18. 18

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

  19. 19

    Java generics, call T method as T and not as its superclass

  20. 20

    Subscript an Arrary of generics type: error: Cannot subscript a value of type '[T]'

  21. 21

    Can you have protocol extension for a specific generics type in Swift?

  22. 22

    Understanding swift generics vs treating parameters as a protocol or base type

  23. 23

    Can you have protocol extension for a specific generics type in Swift?

  24. 24

    Type Safety using Generics : Check T to Interface<T>

  25. 25

    Kotlin: Generics, reflection and the difference between type T and T:Any

  26. 26

    Mockito.any() to match any instance of generics type T

  27. 27

    Java Generics bounded type doesn't apply to method parameters

  28. 28

    (Generics)Cannot make a static reference to the non-static type T

  29. 29

    Java Generics Clarification( Constraining T to a type, while using Comparable)

HotTag

Archive