gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 07:59:13 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()

编译器说:“Type P不符合protocol P”(或者,在以后的Swift版本中,“不支持使用'P'作为符合protocol'P'的具体类型)。
为什么不?不知怎么的,这感觉像是语言上的一个漏洞。我意识到问题源于将数组 arr声明为协议类型的数组,但这是不合理的吗?我认为协议确实有助于提供类似类型层次结构的结构?

最佳答案

编辑:使用Swift又工作了18个月,这是另一个主要版本(提供了一个新的诊断),来自@AyBayBay的评论让我想重写这个答案。新诊断是:
“不支持将'P'用作符合协议'P'的具体类型。”
这实际上让事情变得更清楚了。此扩展名:

extension Array where Element : P {

不适用于 Element == P时,因为 P不被视为 P的具体一致性。(下面的“放在盒子里”解决方案仍然是最通用的解决方案。)
旧答案:
这是元类型的另一种情况。斯威夫特真的希望你找到一个具体的类型,为大多数非琐碎的事情。 [P]不是具体类型(不能为 P分配已知大小的内存块)。(我不认为这是真的;你完全可以创造一些大小 P的东西,因为 it's done via indirection)我不认为有任何证据表明这是一个“不应该”的情况。这看起来很像他们的一个“还没用”的案子。(不幸的是,几乎不可能让苹果确认这些情况之间的区别)事实上 Array<P>可以是一个变量类型(其中 Array不能)表明他们已经在这个方向上做了一些工作,但是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/47159499/

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