繁体   English   中英

T不同的通用对象的异构数组

[英]Heterogeneous Array of generic object where T is different

这是我的类BaseSection实现Collection ,它看起来像这样:

class BaseSection<T:Equatable> {

var items:[T]?

required init(items:[T]){
   self.items = items
  }
}

let sectionTop = BaseSection<TopItem>(items:["foo","bar","yo"])
let sectionBottom = BaseSection<BottomItem>(items:["foo","bar","yo"])

对于此演示,我正在构造可Equatable的字符串对象部分,但此处未列出具有String集合实现的一个属性的项目构造对象。 我需要将两个对象都保存在数组中,即使它们的基类相同,也无法做到。

let sections = [sectionTop, sectionBottom]
heterogeneous collection literal could only be inferred to '[Any]' add explicit type annotation....

即时通讯花了很多时间解决许多问题,但在这里无法实现我的目标。 任何帮助将非常感激

Edit: I have uploaded the sample code to gitHub so you can get a better grasp of what im doing 

github链接

快速自定义通用类型中的becos都是不变的,这意味着BaseSection<TopItem>BaseSection<BottomItem>没有关系,因此二者的唯一常见类型是Any ,您可以按照评论中的链接获取更多信息,作为摘要

  1. 数组/ Dict是协方差的
  2. 闭包参数类型是协方差,闭包返回类型是协方差
  3. 自定义通用类型是不变的

另外,Arrays / Dict是struct,这意味着它们是按值传递的,因此将它们视为协方差是安全的

您似乎正在构建的是一种随着数据变化自动执行表视图更改的机制。 很普通的。 我强烈建议您查看ListDiff ,这是计算更改的有用起点。 (在我自己的代码中,我使用重写版本的ListDiff,因此此处的示例未经测试,但应该非常接近。)

目标是创建一组更新操作(从ListDiff示例复制):

import ListDiff

extension Int : Diffable {
    public var diffIdentifier: AnyHashable {
        return self
    }
}
let o = [0, 1, 2]
let n = [2, 1, 3]
let result = List.diffing(oldArray: o, newArray: n)
// result.hasChanges == true
// result.deletes == IndexSet(integer: 0)
// result.inserts == IndexSet(integer: 2)
// result.moves == [List.MoveIndex(from: 2, to: 0), List.MoveIndex(from: 1, to: 1)]
// result.changeCount == 4

这里重要的是您要进行一系列的删除,插入和移动操作。 您可以通过以下几行将其应用于表视图:

extension UITableView {
    func applyChanges(from changeset: Result, forSection section: Int = 0) {
        beginUpdates()

        let deletes = changeset.deletes.map { IndexPath(row: $0, section: section) }
        deleteRows(at: deletes, with: .bottom)

        let inserts = changeset.deletes.map { IndexPath(row: $0, section: section) }
        insertRows(at: inserts, with: .none)

        for move in changeset.moves {
            guard !changeset.deletes.contains(move.from) else { continue }
            moveRow(at: IndexPath(row: move.from, section: section), 
                    to: IndexPath(row: move.to, section: section))
        }

        endUpdates()
    }
}

这里的关键点是对于动画,您只需要索引路径。 您实际上并不需要数据。 因此,计算索引路径并传递它们。 无需泛型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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