【问题标题】:Understanding Swift default valued properties inside a Protocol extension了解协议扩展中的 Swift 默认值属性
【发布时间】:2022-01-02 15:18:54
【问题描述】:

我有这个示例协议,它有一个带扩展名的默认值属性。

protocol SampleProtocol{
    var sample:String?{get set}
}
extension SampleProtocol{
    var sample:String?{ get { return nil } set{} }
}

现在,我的 TestClass 实现了 SampleProtocol,如下所示。

class TestClass:SampleProtocol {
    var sample: String?{
        return "TestClass"
    }
}

还有一种辅助方法可以打印来自 SampleProtocol 的样本值。

func printValue(_ value: SampleProtocol){
    print(value.sample)
}

现在问题来了

let testObj = TestClass()
print(testObj.sample) // prints "TestClass"
printValue(testObj) // prints nil

从上面的结果,我需要明白为什么当testObj被类型转换为SampleProtcol时,它考虑的是扩展的默认实现而不是TestClass的实现?

【问题讨论】:

  • 您正在 TestClass 中创建一个新的计算 var,而不是使用协议 var.. 在 TestClass 中尝试这个 var sample: String? = "TestClass"
  • 我不知道其根本原因,但它不起作用,因为您的类中有一个计算属性,如果您将其更改为存储属性,您将获得预期的行为跨度>
  • 哇,将sample 更改为存储属性效果很好。我的意思是,如果你们知道的话,任何解释或 Swift 文档都会非常有帮助。

标签: ios swift iphone macos swift-protocols


【解决方案1】:

问题是TestClass 没有实现SampleProtocol,所以当你在接受SampleProtocolprintValue 方法中传递它时,它将调用协议扩展中的默认实现(因为实例你传递的没有实现协议方法)。

SampleProtocol 中您已将变量定义为 {get set} 但在TestClass 变量中您只提供了一个 getter,这不符合要求(如果您删除协议扩展,您将看到一个错误该类不符合协议)。

如果你提供一个 setter 就可以了:

class TestClass: SampleProtocol {
    var sample: String? {
        get {
        return "TestClass"
        } set { }
    }
}

【讨论】:

    猜你喜欢
    • 2016-12-17
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    相关资源
    最近更新 更多