这里有一段 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 编译器已经崩溃,这表明存在编译器错误。编译器的预期行为应该是在您的代码有效时输出翻译后的代码,否则输出诊断消息。
你可以在 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> = []