了解协议扩展中的 Swift 默认值属性
Posted
技术标签:
【中文标题】了解协议扩展中的 Swift 默认值属性【英文标题】:Understanding Swift default valued properties inside a Protocol extension 【发布时间】: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 文档都会非常有帮助。
【参考方案1】:
问题是TestClass
没有实现SampleProtocol
,所以当你在接受SampleProtocol
的printValue
方法中传递它时,它将调用协议扩展中的默认实现(因为实例你传递的没有实现协议方法)。
在SampleProtocol
中您已将变量定义为 get set 但在TestClass
变量中您只提供了一个 getter,这不符合要求(如果您删除协议扩展,您将看到一个错误该类不符合协议)。
如果你提供一个 setter 就可以了:
class TestClass: SampleProtocol
var sample: String?
get
return "TestClass"
set
【讨论】:
以上是关于了解协议扩展中的 Swift 默认值属性的主要内容,如果未能解决你的问题,请参考以下文章
使用 Swift 4 中的 JSONDecoder,缺少的键可以使用默认值而不是可选属性吗?
使用 Swift 4 中的 JSONDecoder,缺少的键可以使用默认值而不是可选属性吗?