arrays - 当元素明显受限时,为什么 Swift 编译器在推断我的通用元素的类型时会抛出错误?

标签 arrays swift generics compiler-errors

当我正在实现一个保持对其元素的弱引用的数组时,在使用 之前,我在使用 Collection 扩展方法时偶然发现了一个编译错误Collection 方法正确且按预期编译的代码。

预期行为

代码应该可以正确编译。

当前行为

编译器抛出以下两个错误:

  1. WeakRef 需要那个元素?成为类(class)类型
  2. 无法推断“项目”的类型

可能的解决方案

我找到的唯一解决方案是公开属性项并使用 for 循环而不是 Collection 扩展方法。完成此操作后,编译器能够推断出 items 的类型,甚至 Collection 方法也能正常工作。

重现步骤

首先实现WeakRef类:

final class WeakRef<T: AnyObject> {

    weak var value: T?

    init(_ value: T) {
        self.value = value
    }

}

第二个实现 WeakArray 结构:

struct WeakArray<Element: AnyObject> {

    public var items: [WeakRef<Element>] = []

    init(_ elements: [Element]) {
        items = elements.map { WeakRef($0) }
    }
}

第三个实现Collection扩展实现:

extension WeakArray: Collection {

    var startIndex: Int { return items.startIndex }
    var endIndex: Int { return items.endIndex }

    subscript(_ index: Int) -> Element? {
        return items[index].value
    }

    func index(after idx: Int) -> Int {
        return items.index(after: idx)
    }

}

第四次创建 WeakArray 属性的实例,但不在同一个源文件中,而是作为 WeakArray 例如:

var objects: WeakArray<UIViewController> = WeakArray.init([])

第五步也是最后一步调用 Collection 协议(protocol)的方法,例如:

objects.forEach({ $0?.view.backgroundColor = .white })

上下文(环境)

此代码无法在使用 Swift 4.1 的 Xcode 版本 9.3.1 (9E501) 上编译

附加说明

上述代码的解决方案在以下链接中找到:

  1. https://marcosantadev.com/swift-arrays-holding-elements-weak-references/
  2. https://www.objc.io/blog/2017/12/28/weak-arrays/

提前感谢您提供的任何帮助。这篇文章经过完全编辑以符合 Stackoverflow 提出问题的标准。特别感谢 MartinR 指导我在 Stackoverflow 上发布了一个很好的问题。

最佳答案

一个 Collection 有一个关联的 Element 类型,这似乎 与您的通用 Element 占位符冲突。使用不同的 占位符的名称 E 解决了这个问题:

struct WeakArray<E: AnyObject> {

    public var items: [WeakRef<E>] = []

    init(_ elements: [E]) {
        items = elements.map { WeakRef($0) }
    }
}

extension WeakArray: Collection {

    var startIndex: Int { return items.startIndex }
    var endIndex: Int { return items.endIndex }

    subscript(_ index: Int) -> E? {
        return items[index].value
    }

    func index(after idx: Int) -> Int {
        return items.index(after: idx)
    }
}

关于arrays - 当元素明显受限时,为什么 Swift 编译器在推断我的通用元素的类型时会抛出错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50487948/

相关文章:

linux - HP 机器上 Linux 中的竞争条件检测器?

java - Java 中的 T 和继承

java - 在 Java 中的一个 println 语句中打印数组的所有元素

ios - Swift - 必须调用父类(super class) SKSpriteNode 错误的指定初始值设定项

java - 创建数组数组的动态数组的最佳方法是什么

arrays - 我可以在 Array 上创建一个约束扩展,以便它只在 [CGPoint] 上运行吗

ios - 自定义委托(delegate)和数据源 NSObject 最佳实践

delphi - 包含 TObjectList<T> 的 TGenericClass<T> 无法编译

Javascript:将对象列表转换为关联数组

java - 如何将所有字节发送到单个数组中,然后在字节之间进行异或?