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

Swift 2.0:协议扩展:具有相同功能签名的两个协议编译错误

景育
2023-03-14
问题内容

给定两个协议及其扩展名:

protocol FirstDelegate {
    func someFunc()
}

protocol SecondDelegate {
    func someFunc()
}

extension FirstDelegate {
    func someFunc() {
        print("First delegate")
    }
}

extension SecondDelegate {
    func someFunc() {
        print("Second delegate")
    }
}

并尝试使它们都符合:

class SomeClass: FirstDelegate, SecondDelegate {}

我收到编译时错误:

类型“ SomeClass”不符合协议“ FirstDelegate”

交换FirstDelegateSecondDelegate

class SomeClass: SecondDelegate, FirstDelegate {}

产生反向:

类型“ SomeClass”不符合协议“ SecondDelegate”

删除扩展之一可以解决此问题。同上为someFunc()内部提供实现SomeClass

这个协议扩展功能对我来说还很新。此外,目前苹果官方的“快速编程指南(预发行版)”中有关此信息的信息很少。

我是否违反了某些协议扩展规则?


问题答案:

协议定义了一致性类型的要求(方法,属性等)。

protocol FirstDelegate {
    func someFunc()
}

protocol SecondDelegate {
    func someFunc()
}

用相同的必需方法定义了两个协议someFunc()。一致类型必须实现此方法:

class SomeClass: FirstDelegate, SecondDelegate {
    func someFunc() {
        print("SomeClass implementation")
    }
}

协议扩展 提供了方法和属性实现,以符合的类型。协议扩展的一种特殊情况是 默认实现 ,即您在此处定义的内容:

extension FirstDelegate {
    func someFunc() {
        print("First delegate")
    }
}

someFunc()为符合的所有类型定义的默认实现FirstDelegate。由于这是该协议 唯一
需要的方法,因此一致性类根本不需要定义该方法:

class SomeClass: FirstDelegate {

}

SomeClass().someFunc() // Output: First delegate

但是, 如果 该类提供了自己的实现,则将使用该实现:

class SomeClass: FirstDelegate {
    func someFunc() {
        print("SomeClass implementation")
    }
}

SomeClass().someFunc() // Output: SomeClass implementation

在您的情况下,您已经定义someFunc()两种 协议的默认实现:

extension FirstDelegate {
    func someFunc() {
        print("First delegate")
    }
}

extension SecondDelegate {
    func someFunc() {
        print("Second delegate")
    }
}

如果一个类提供了所需方法的自己的实现,则它仍然可以同时符合两种协议:

class SomeClass: FirstDelegate, SecondDelegate {
    func someFunc() {
        print("SomeClass implementation")
    }
}

但是该类 无法 通过使用默认实现来符合

class SomeClass: FirstDelegate, SecondDelegate {

}

对于这两个协议,因为存在 冲突 。未指定应使用哪种默认实现,这就是编译器抱怨的原因。

实际上,该类现在不符合 任何 协议。在报告导航器的完整编译器日志中可以看到:

main.swift:24:7:错误:类型“ SomeClass”不符合协议“ FirstDelegate”
class SomeClass:FirstDelegate,SecondDelegate {
      ^
main.swift:5:10:注意:多个名为'someFunc()'且类型为(()->()'的匹配函数
    func someFunc()
         ^
main.swift:19:10:注意:候选人完全匹配
    func someFunc(){
         ^
main.swift:13:10:注意:候选人完全匹配
    func someFunc(){
         ^
main.swift:24:7:错误:类型“ SomeClass”不符合协议“ SecondDelegate”
class SomeClass:FirstDelegate,SecondDelegate {
      ^
main.swift:9:10:注意:多个名为'someFunc()'且类型为'()->()'的匹配函数
    func someFunc()
         ^
main.swift:19:10:注意:候选人完全匹配
    func someFunc(){
         ^
main.swift:13:10:注意:候选人完全匹配
    func someFunc(){
         ^


 类似资料:
  • 问题内容: 我正在使用swift 2.0,我有一个协议和对该协议的扩展来创建方法的默认实现,代码如下: 稍后,我在代码中尝试调用此方法,并收到一条错误消息: “不能在不可变值上使用变异成员:’自身’是不可变的” 代码如下: 我唯一想到的是这种情况下的“ Self”是协议,而不是类。但是,我必须缺少一些东西才能使该概念起作用。该协议定义的方法的默认实现,该方法还可以编辑同一协议定义的值。 谢谢您的帮

  • 扩展说明 RPC 协议扩展,封装远程调用细节。 契约: 当用户调用 refer() 所返回的 Invoker 对象的 invoke() 方法时,协议需相应执行同 URL 远端 export() 传入的 Invoker 对象的 invoke() 方法。 其中,refer() 返回的 Invoker 由协议实现,协议通常需要在此 Invoker 中发送远程请求,export() 传入的 Invoker

  • 协议和扩展 你可以扩展一个已经存在的类型来采纳和遵循一个新协议, 就算是你无法访问现有类型的源代码也行. 扩展可以添加新的属性、方法和下标到已经存在的类型, 并且因此允许你添加协议需要的任何需要. protocol TextRepresentable { var textualDescription: String { get } } // 此处并无Dice这个类, 以及其sides属性

  • 问题内容: 我有一个协议扩展,它过去在swift 2.2之前可以完美地工作。 现在我有一个警告,告诉我使用新的,但是如果我添加它 没有使用Objective-C选择器声明任何方法。 我尝试通过以下几行代码重现该问题,可以轻松将其复制并粘贴到操场上 还有一个建议在协议中附加到该方法,但是如果我这样做,它还会要求我将其添加到实现该方法的类中,但是一旦添加,该类便不再符合该协议,因为它不符合该协议似乎看

  • 据我所知,协议缓冲区主要用于控制服务器和客户端代码的项目。我的一般问题是——协议缓冲区能否用于将二进制消息序列化/反序列化到使用现有协议的服务器?所以,我的问题: > 如果协议缓冲区不支持本机微调现有协议的序列化/反序列化方式,那么可以通过扩展添加该功能吗?是否可以以某种方式添加序列化/反序列化方法可以识别的关键字?也许这可以通过扩展或修改protobuf csharp port或protobuf

  • 问题内容: 我正在尝试使用Swift协议扩展,却发现这种行为令人困惑。您能帮我得到我想要的结果吗? 请参阅代码最后4行的注释。(如果需要,可以将其复制粘贴到Xcode7游乐场)。谢谢!! 问题答案: 简短的答案是协议扩展不执行类多态性。这是有一定道理的,因为协议可以被结构或枚举采用,并且因为我们不希望仅在没有必要的地方采用协议来引入动态调度。 因此,在中,实例变量(可能更准确地写为)并不意味着您认