为什么这个 swift 代码会导致类型检查错误?我在 Swift 5

问题描述 投票:0回答:1

这里有一段 swift 测试代码,为什么它不起作用?如何让它工作?

import UIKit

class SwiftTestController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        test()
    }
    
    func test() {
        let resourceViews: Array<any ResourceView> = []
       // type-checking error in this line.
        let resources = resourceViews.map { $0.resource }
    }
}


protocol ResourceComponent {
    
}

// fine
protocol ResourceView: ResourceComponent {
    associatedtype R: Resource
    var resource: R { get set }
}

// does not working
//protocol ResourceView: UIView, ResourceComponent {
//    associatedtype R: Resource
//    var resource: R { get set }
//}

// does not working
//protocol ResourceView: UIView {
//    associatedtype R: Resource
//    var resource: R { get set }
//}

protocol Resource {}

下面是详细错误信息的图片!

ResourceView
不继承(约束)
UIView
工作正常。

我提交了一个issue.

swift
1个回答
1
投票

错误看起来像是编译器的堆栈跟踪,这意味着 Swift 编译器已经崩溃,这表明存在编译器错误。编译器的预期行为应该是在您的代码有效时输出翻译后的代码,否则输出诊断消息。

你可以在 Swift GitHub Repo 报告这个。

根据我的调查,它似乎会因段错误而崩溃

  • 协议是类绑定的,并且;
  • 您正在打开存在并访问具有关联类型的事物之一。

隐式打开existentials是一个相对较新的功能,如果那里还有一些错误我也不会感到惊讶。

无论如何,我发现将

resourceViews
声明为
ResourceView
UIView
之间的交集类型有效:

protocol ResourceView:  ResourceComponent { // remove the class bound
    ...
}

let resourceViews: Array<any ResourceView & UIView> = []

map
行的类型约束在这里几乎相同(我认为),但 Swift 对此很满意。

这里的区别当然是非

UIView
现在可以符合
ResourceView
,但最终他们不能进入
resourceViews
数组,所以我认为这可能是一个可行的解决方案目前。还有一些细微差别,我认为对你的情况来说不太重要,答案是here.

也许稍微重命名也会有所帮助:)

protocol ResourceComponent {
    
}

protocol ResourceBox:  ResourceComponent {
    associatedtype R: Resource
    var resource: R { get set }
}

protocol Resource {
    
}

typealias ResourceView = any ResourceBox & UIView

let resourceViews: Array<ResourceView> = []
© www.soinside.com 2019 - 2024. All rights reserved.