繁体   English   中英

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

[英]Why does the Swift Compiler throw an error on inferring the type of my Generic Element when the Element is clearly constrained?

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

预期的行为

代码应该编译没有错误。

当前行为

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

  1. WeakRef需要Element吗? 是一个类型
  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协议的方法,例如:

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)
    }
}

暂无
暂无

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

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