当前位置: 首页 > 面试题库 >

协议不符合自身?

颜杰
2023-03-14
问题内容

为什么此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不符合协议P”(或在Swift的更高版本中,“不支持将’P’用作符合协议’P’的具体类型”。)

为什么不?某种程度上,这感觉就像是语言上的一个漏洞。我意识到问题源于将数组声明arr协议类型
的数组,但这是不合理的事情吗?我认为协议确实可以帮助提供类型分层结构之类的结构吗?


问题答案:

编辑:使用Swift还要工作18个月,Swift是另一个主要版本(提供新的诊断),并且@AyBayBay的评论使我希望重写此答案。新的诊断是:

“不支持将“ P”用作符合协议“ P”的具体类型。”

这实际上使整个事情变得更加清晰。此扩展名:

extension Array where Element : P {

Element == P由于P不能视为的具体符合,因此不适用于P。(下面的“放在盒子里”解决方案仍然是最通用的解决方案。)

旧答案:

这是元类型的另一种情况。 斯威夫特(Swift) 确实
希望您对大多数不重要的事情都采取具体的态度。 [P]不是具体类型(您不能为分配大小已知的内存块 P)。
(我不认为这是真的,您可以绝对创建大小的东西,P因为它是通过间接完成的。)我不认为有任何证据表明这是“不应该”工作的情况。这看起来很像是他们的“不起作用”案例之一。(不幸的是,要让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了自动执行相同功能的功能。



 类似资料:
  • 问题内容: 我试图在我快速编写的类上使用NSCoding协议,但是似乎无法弄清楚为什么当我实现所需的方法时,编译器会抱怨它“不符合协议NSCoding”: 这是一个错误还是我只是缺少一些东西? 问题答案: 如您在报告导航器中详细的编译器消息中所见,您的方法未正确声明: (在beta版本之间可能有所变化。)此外,该方法必须标记为: 在 Swift 3中 ,所需的方法是

  • 问题内容: 编译错误如下: 类型“ AnyObject”不符合协议“ SequenceType” 这种压力是什么? 谁能帮我很多忙! 问题答案: 苹果在Swift编程语言中指出: for-in循环针对范围,序列,集合或进度中的每个项目执行一组语句。 目前,它仅符合protocol ,因此您无法在其上使用for循环。如果要这样做,则必须执行类似以下操作:

  • 问题内容: Beta 3一切正常,现在出现一个奇怪的错误,而且我不知道如何解决它。尝试了所有类似问题的解决方案。 这是我的代码: 两条标记线都给了我相同的错误: 类型“ String.Index”不符合协议“ IntegerLiteralConvertible” 有人能帮我吗?还是Beta 4有漏洞?谢谢! 问题答案: 在Beta 4中,Swift的String.Index处理再次发生了变化- 现

  • 问题内容: 为什么我要有一个数组并在其中放入一堆不同大小的类型… …除了和.... 文档说明: “ AnyObject可以代表任何类类型的实例” 但是,当我命令点击,或者看到这些类型的标准库定义,我看到他们都值。 这里的根本问题是什么?为什么这样设计? 问题答案: Swift中有两种类型的东西- 可以真正容纳任何东西-结构,枚举或类,以及只能容纳类。 有时似乎可以保留结构的原因是,某些特定类型会根

  • 本文向大家介绍Objective-C语言符合协议,包括了Objective-C语言符合协议的使用技巧和注意事项,需要的朋友参考一下 示例 以下语法表明类使用尖括号括起来的协议。 这意味着NewClass的任何实例都将响应其接口中声明的方法,但也将为的所有必需方法提供实现NewProtocol。 一个类也可以通过用逗号分隔来遵循多个协议。 就像遵循单个协议时一样,该类必须实现每个协议的每个必需方法以

  • 问题内容: 我正在尝试为我们的应用程序快速制作一个简单的依赖注入系统,为期2天。我对任何解决方案都比较灵活,但是我想要一些东西,所以我可以说“给我一个符合该协议的实例”,返回的实际类型可以是只要符合所述协议的任何类型。我已经尝试了很多方法,包括泛型,但是设法弄清了它是否真的可以工作,所以现在我只涉及基本知识,例如: 我知道它并不漂亮,但是现在,我对性能/错误代码并不挑剔,只要它能解决解耦问题(最好