gpt4 book ai didi

swift - 协议(protocol)不符合自身?

转载 作者:IT王子 更新时间:2023-10-29 04:56:10 25 4
gpt4 key购买 nike

为什么这个 Swift 代码不能编译?

protocol P { }
struct S: P { }

let arr:[P] = [ S() ]

extension Array where Element : P {
func test<T>() -> [T] {
return []
}
}

let result : [S] = arr.test()

编译器说:“类型 P 不符合协议(protocol) P”(或者,在更高版本的 Swift 中,“不支持使用 'P' 作为符合协议(protocol) 'P' 的具体类型。”)。

为什么不呢?不知何故,这感觉像是语言上的一个漏洞。我意识到问题源于声明数组 arr作为协议(protocol)类型的数组,但这是不合理的事情吗?我认为协议(protocol)确实可以帮助提供具有类型层次结构之类的结构吗?

最佳答案

编辑:与 Swift 一起工作 18 个月,另一个主要版本(提供新的诊断),以及来自 @AyBayBay 的评论让我想重写这个答案。新的诊断是:

"Using 'P' as a concrete type conforming to protocol 'P' is not supported."



这实际上使整个事情变得更加清晰。这个扩展:
extension Array where Element : P {

不适用于 Element == PP不被视为 P 的具体一致性. (下面的“把它放在一个盒子里”的解决方案仍然是最通用的解决方案。)

旧答案:

这是元类型的另一种情况。 Swift 真的希望你为大多数非平凡的事情找到一个具体的类型。 [P]不是具体类型(您不能为 P 分配已知大小的内存块)。 (我认为这不是真的;你绝对可以创建大小为 P 的东西,因为 it's done via indirection 。)我认为没有任何证据表明这是“不应该”工作的情况。这看起来很像他们的一个“还不行”的案例。 (不幸的是,几乎不可能让 Apple 确认这些案例之间的差异。) Array<P> 的事实。可以是变量类型(其中 Array 不能)表明他们已经在这个方向上做了一些工作,但是 Swift 元类型有很多尖锐的边缘和未实现的情况。我认为你不会得到比这更好的“为什么”答案。 “因为编译器不允许。” (不满意,我知道。我的整个 swift 生活……)

解决方案几乎总是把东西放在一个盒子里。我们制作了一个类型橡皮擦。
protocol P { }
struct S: P { }

struct AnyPArray {
var array: [P]
init(_ array:[P]) { self.array = array }
}

extension AnyPArray {
func test<T>() -> [T] {
return []
}
}

let arr = AnyPArray([S()])
let result: [S] = arr.test()

当 Swift 允许您直接执行此操作时(我确实希望最终这样做),它可能只是通过自动为您创建此框。递归枚举正好有这样的历史。你不得不把它们装箱,这非常烦人和限制,最后编译器添加了 indirect更自动地做同样的事情。

关于swift - 协议(protocol)不符合自身?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33112559/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com