简体   繁体   中英

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

I'm getting an error message when trying to use Generics in Swift. I'm trying to create a function that takes any object that inherits from Parent , and modify an inout reference which just so happens to be an Array of T: Parent

func myFunction<T: Parent>(data: NSDictionary, inout objects: Array<T>) {
    let myArray = data.valueForKey("the_array") as NSArray

    for object in myArray {
        var addMe: Object = Object()
        //...

        objects.append(addMe) //'Object' is not convertible to 'T'
    }

}

I'm passing this into the function higher up the stack.

var objects: [Object] = []

myClass.myFunction(data, objects: &objects)

Even though Object is defined as follows, inheriting from Parent

class Object: Parent {
    //...
}

It gives me an error that it can't convert Object to T .. although I'm probably mis-interpreting the error message. Does anyone see what I'm doing wrong?

You're trying to add an Object to an array of T : Parent . But just because Object is a subclass of Parent doesn't mean T is Object . At runtime, T could be Dinosaur , another subclass of Parent , and adding addMe to that array would be invalid.

One solution is to initialize addMe as T() , and optionally cast to Object , like so:

for object in myArray {
    var addMe = T()

    if let addMe = addMe as? Object {
        // do Objecty stuff here
    }

    //...

    objects.append(addMe)
}

I believe Aaron has you on the right track, but note that this probably means a misuse of generics. You more likely meant:

func myFunction(data: NSDictionary, inout objects: [Parent]) { ... }

There is no reason to say "T, where T is a subclass of Parent." That is just "Parent" in most OOP systems (including Swift).

This is also a very surprising way to handle your return. The normal approach in Swift would be:

func myFunction(data: [String : [Object]) -> [Parent] { ... }

It is extremely uncommon in Swift to pass an empty array and have the function fill it in. You generally generate the array and return it. Swift has excellent copy-on-write semantics that make this cheap (unlike C++ per-move-semantics, where this pattern is more common).

Wherever possible, try to use Swift Arrays and Dictionaries rather than NSArray and NSDictionary . You will save a lot of complicated as? conversions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM