Swift协议:属性区别(获取,获取设置)🏃🏻‍♀️🏃🏻

面向协议的程序设计是iOS中的新趋势,尽管它是迅速引入的,但它已经有几年历史了。 Swift是一种新时代的语言,并且在每次迭代中都变得越来越强大。 在2015年的WWDC中,我们都遇到了Dave Abrahams的Crusty,他解释了POP的重要方面。 我真的建议您仔细阅读一次,以更好地了解POP。

Swift中面向协议的编程– WWDC 2015 –视频– Apple Developer

Swift的设计核心是两个令人难以置信的强大创意:面向协议的编程和一流的价值……

developer.apple.com

我还建议阅读Raywenderlich的教程Niv Yahel撰写的POP简介,它也可以在操场上进行讲解和实际操作。

协议定义了适合特定任务或功能的方法,属性和其他要求的蓝图。 然后,该协议可以由类,结构或枚举采用,以提供这些要求的实际实现。 满足协议要求的任何类型都被称为符合该协议。 苹果文件。

 协议SomeProtocol { 
var mustBeSettable:Int {获取设置}
var didNotNeedToBeSettable:Int {get}
}

协议声明一致性类型必须通过在声明主体中包含协议属性声明来实现属性。 它具有变量声明的特殊形式:

  Var propertyName:类型{获取设置} 

与其他协议成员声明一样,这些属性声明仅声明符合协议的类型的getter和setter要求。 因此,您不能直接在声明它的协议中实现getter或setter。

可以通过多种方式通过符合类型来满足吸气剂和设置剂的要求。 如果属性声明同时包含getset关键字,则符合条件的类型可以使用存储的变量属性或既可读又可写的计算属性(即,同时实现getter和setter的)来实现它。 但是,该属性声明不能实现为常量属性或只读的计算属性。 如果属性声明仅包含get关键字,则可以将其实现为任何类型的属性。 有关实现协议的属性要求的符合类型的示例,请参见属性要求。

  • 对于Gettable Protocol Properties ,可以通过任何种类的属性来满足要求,并且对于可用于您自己的代码的属性,也可以设置该属性是有效的。
  • 对于“可获取和可设置的协议属性” ,不能通过始终存储的属性或只读的计算属性来满足要求。
  • 协议中的属性要求始终被声明为变量属性,因为它们被声明为计算属性。
  1. Gettable —常量属性
 协议FullyNamed { 
var fullName:String {get}
}
struct Detective:FullyNamed {
let fullName:字符串
}
让大力神=侦探(全名:“ Hercule Poirot”)
print(hercule.fullName)//返回“ Hercule Poirot”

2. Getable-可变属性

 协议FullyNamed { 
var fullName:String {get}
}
struct Detective:FullyNamed {
var fullName:字符串
}
var bond = Detective(fullName:“ Bond”)
print(bond.fullName)//返回“ Bond”
bond.fullName =“詹姆斯·邦德”
print(bond.fullName)//返回“詹姆斯·邦德”

3.可获取的—计算属性

 协议FullyNamed { 
var fullName:String {get}
}
struct Detective:FullyNamed {
fileprivate变量名称:字符串
var fullName:String {
返回名称
}
}
让蝙蝠侠=侦探(名字:“布鲁斯·韦恩”)
print(batman.fullName)//返回“布鲁斯·韦恩”

4. Gettable-私人套装

 协议FullyNamed { 
var fullName:String {get}
}
公共结构侦探:FullyNamed {
public private(set)var fullName:字符串
public init(fullName:String){
self.fullName = fullName
}
公共变异函数func namedWith(fullName:String){
self.fullName = fullName
}
}
var holmes = Detective(fullName:“ Holmes”)
print(holmes.fullName)//返回“霍姆斯”
holmes.renameWith(fullName:“夏洛克·福尔摩斯”)
print(holmes.fullName)//返回“夏洛克·福尔摩斯”

5.可获取和可设置-计算属性

 协议FullyNamed { 
var fullName:String {get}
}
struct Detective:FullyNamed {
fileprivate变量名称:字符串
var fullName:String {
得到{
返回名称
}
设置{
名称= newValue
}
}
}
var Payne =侦探(名称:“ Payne”)
print(Payne.fullName)//返回“ Payne”
Payne.fullName =“最大佩恩”
print(Payne.fullName)//返回“ Max Payne”

6.可获取和可设置-常量属性

 协议FullyNamed { 
var fullName:String {获取设置}
}
struct Detective:FullyNamed {
let fullName:字符串
}
让Rorschach =侦探(全名:“ Walter Joseph Kovacs”)
//错误消息:类型“侦探”不符合协议“ FullyNamed”

7. Gettable&Settable —仅获得定义

 协议FullyNamed { 
var fullName:String {获取设置}
}
struct Detective:FullyNamed {
私有变量名称:字符串
var fullName:String {
返回名称
}
}
var constantine =侦探(名字:“约翰·康斯坦丁”)
//错误消息:类型“侦探”不符合协议“ FullyNamed”

协议中的Get Property,不强制一致类型仅声明get属性,它也可以其声明为Set属性,如上所述。 请检查此示例以更清楚。

 协议FullyNamed { 
var firstName:字符串{get}
var lastName:字符串{获取设置}
}
struct SuperHero:全名{
var firstName =“超级”
var lastName =“男人”
}
var dcHero = SuperHero()
print(dcHero)// SuperHero(firstName:“ Super”,lastName:“ Man”)
dcHero.firstName =“蝙蝠”
dcHero.lastName =“女孩”
print(dcHero)// SuperHero(firstName:“蝙蝠”,lastName:“女孩”)

即使FullyName协议将firstName声明为get only,我们仍然可以更改其值。 这是因为FullyName不会停止符合类型来设置属性
如果我们将dcHero显式转换为FullyNamed,则编译器将不允许我们设置firstName,因为它不知道设置程序。

  var anotherDcHero:FullyNamed = SuperHero() 
打印(另一个DcHero)
anotherDcHero.firstName =“蝙蝠”
//错误:无法分配给属性:“ firstName”是仅获取属性
anotherDcHero.lastName =“女孩”
打印(另一个DcHero)

在声明上方,设置firstName时给出编译时错误。 在此详细说明此特定示例。

谢谢阅读!!!

如有任何疑问,请随时发表评论。 也欢迎任何讨论! 快乐编码! 💚💚💚💚💚💚