Search code examples
swiftgenericsrealmrealm-list

swift generics: append not found for array


My first attempt to use swift generics:

extension RealmSwift.List where Element == Object {
    // @deprecated use RealmSwift.List<>
    func arrayo<T: Object>() -> [T] {
        var res: [T] = []
        for card in self {
            res.append(card) <- here I got 

No exact matches in call to instance method 'append'

        }
        return res
    }

    convenience init<T: Object>(objects: [T]) {
        self.init()
        for card in objects {
            append(card)
        }
    }
}

what's a good way to write this adapter once and for all?


Solution

  • Notice the where Element. You can refer to the type of the list items using Element, so you do not need to set up another type parameter T. card is of type Element not T, so you cannot add it to the Array<T>. There is no guarantee that T and Element are equivalent so the compiler doesn't allow it. The same applies for your convenience init.

    extension RealmSwift.List where Element == Object {
        // @deprecated use RealmSwift.List<>
        func arrayo() -> [Element] {
            var res: [Element] = []
            for card in self {
                res.append(card) // Now you are adding an `Element` to the array of `Element` so it will work.
            }
            return res
        }
    
        convenience init(objects: [Element]) {
            self.init()
            for card in objects {
                append(card)
            }
        }
    }
    

    But generics are not really useful here because you are constraining Element to Object already. So there is only one potential type - You could make arrayo() and the init use Object directly.

    To make this useful do

    extension RealmSwift.List where Elemtn: RealmCollectionValue