Array function and generic types

I'm complety lost with Generic types


In a class, I've declare an array, like this:


class ResponseListl: Decodable {
    var moderators: [T]
}


this intends to get differnt values of T thru an internet connection.

No problem to fill the array in a first time, but if I want to grow this array thru a second connection, I try to make this:

moderators.append (data) (data is of type T) the compiler returns me the error:


Cannot invoke 'append' with an argument list of type '([T])'


What is wrong with this?

Answered by OOPer in 408556022

I guess your class header also missing generic declaration:


class ResponseListModel<T: Decodable>: Decodable {


In this case, you cannot declare another `T` in your `fetch` method.

That make another generic type `T`, which is not the same as `T` for `ResponseListModel`.

The two `T`s are different types, so you cannot add `rep.moderators` to `self.moderators`, even if you use the right method.

No problem to fill the array in a first time, but if I want to grow this array thru a second connection, I try to make this:

moderators.append (data) (data is of type T) the compiler returns me the error:


Could you show this part of code with append ?


Did you show the real code ?

Surprising that the compiler accepts your class definition ?


Should get an error as

Type 'ResponseListl' does not conform to protocol 'Decodable'

No of course it isn't the real code

I wanted to isolate the response of the compiler

The Code is quite complex


class ResponseListModel: Decodable {
    var moderators: [T]
    var totalEnreg: Int
    var hasMore: Bool
    var currentPage: Int
    var indexPage: Int = 0
    var limit: Int = 0
    var nbPagesInMemory: Int!
    var fetchingData: Bool = true
   
    enum CodingKeys: String, CodingKey {
        case moderators = "items"
        case hasMore = "has_more"
        case totalEnreg = "total"
        case currentPage = "page"
    }
   
    func destroyPageData(_ index: Int) {
        moderators.removeSubrange(index..<index+min(limit, moderators.count))<br="">    }
   
    func rowLoaded (_ row: Int) -> Bool {
        let firstIndex = (currentPage-1)*limit
        let lastIndex = firstIndex + moderators.count
        return row >= firstIndex && row < lastIndex
    }
   
    func rowIndex (_ row: Int) -> Int {
        return row - (currentPage - 1)*limit
    }
   
    func row(_ row: Int) -> T {
        let rowCalculee = row - (currentPage-1)*limit
        return moderators[rowCalculee]
    }
   
    func clean() {
        moderators.removeAll()
    }
   
    func fetch(_ tableview: NSTableView, _ row: Int, params: Parameters, response: ResponseListModel.Type, completion: @escaping (Bool) -> Void) where T: Decodable {
    Swift.print("ca tourne pour row=\(row)")
            if !fetchingData /*|| !rowLoaded(row)*/ {
                fetchingData = true
                // 1 calculate what part of the array has to be destroyed
                if row < indexPage {
                    destroyPageData((nbPagesInMemory-1)*limit)
                } else {
                   destroyPageData(0)
                    self.indexPage += limit
                }
               
                // 2 Fetch data if necessary
               
                StackExchangeClient().fetch(request: BaseRequest(parameters: params), dataResponse: response, completion: {
                    result in
                    switch result{
                    case .failure(_):
                        completion(false)
                    case .success(let response):
                        let rep = response as! ResponseListModel
                        self.currentPage += rep.moderators.count / self.limit
                        if row < self.indexPage {
                            self.moderators.insert(rep.moderators, at: 0)
                        } else {
                            self.moderators.insert(contentsOf: rep.moderators, at: self.moderators.count)
                        }
                        self.moderators.append(rep.moderators)
                       
                        let rows = NSIndexSet(indexesIn: NSMakeRange(row, self.indexPage+self.moderators.count-1)) as IndexSet
                        let cols = NSIndexSet( indexesIn: NSMakeRange(0, tableview.numberOfColumns)) as IndexSet
                        DispatchQueue.main.async {
                            self.fetchingData = false
                            tableview.reloadData(forRowIndexes: rows, columnIndexes: cols)
                        }
                        completion(true)
                    }
                })
        }
}

I can't correctly reproduce the header of the fetch function with the advance.button of this forum, it corrects the code

my code is


func fetch<T>(_ tableview: NSTableView, _ row: Int, params: Parameters, response: ResponseListModel<T>.Type, completion: @escaping (Bool) -> Void) where T: Decodable {

}


and my problem appears on lines 63 and 65

What do you get if you change this line:

                        self.moderators.append(rep.moderators) 

to:

                        self.moderators.append(contentsOf: rep.moderators) 
Accepted Answer

I guess your class header also missing generic declaration:


class ResponseListModel<T: Decodable>: Decodable {


In this case, you cannot declare another `T` in your `fetch` method.

That make another generic type `T`, which is not the same as `T` for `ResponseListModel`.

The two `T`s are different types, so you cannot add `rep.moderators` to `self.moderators`, even if you use the right method.

I think you are right

The declaration of the fetch function as simply to be:

func fetch(_ tableview: NSTableView, _ row: Int, params: Parameters, response: ResponseListModel<T>.Type, completion: @escaping (Bool) -> Void) {

}


in this case, the compiler accepts

self.moderators.insert(contentsOf: rep.moderators, at: 0)

Array function and generic types
 
 
Q