Swift 4語言為類,枚舉或結構體提供關聯值的屬性。 屬性可以進一步分為存儲屬性和計算屬性。
存儲屬性和計算屬性的區別
存儲屬性 | 計算屬性 |
---|---|
將常量和變數值存儲為實例 | 計算值而不是存儲值 |
由類和結構體提供 | 由類,枚舉和結構提供 |
存儲和計算屬性都與實例類型相關聯。 當屬性與其類型值相關聯時,它將被定義為“類型屬性”。 存儲和計算屬性通常與特定類型的實例相關聯。 但是,屬性也可以與類型本身相關聯。 這些屬性稱為類型屬性。 還使用了屬性觀察者。
- 觀察存儲屬性的值
- 觀察從超類派生的繼承子類的屬性
存儲屬性
Swift 4引入了存儲屬性概念來存儲常量和變數的實例。 常量的存儲屬性由let
關鍵字定義,變數的存儲屬性由var
關鍵字定義。
- 在定義期間,存儲屬性提供“默認值”
- 在初始化期間,用戶可以初始化和修改初始值
參考以下代碼 -
struct Number {
var digits: Int
let pi = 3.1415
}
var n = Number(digits: 12345)
n.digits = 67
print("\(n.digits)")
print("\(n.pi)")
當使用playground運行上述程式時,得到以下結果 -
67
3.1415
考慮上面代碼中的以下行 -
let pi = 3.1415
這裏,變數pi
初始化為具有實例pi = 3.1415
的存儲屬性值。 因此,每當引用實例時,它將僅存儲值:3.1415
。
存儲屬性的另一種方法是具有常量結構。 因此,結構體的整個實例將可視為“常量的存儲屬性”。
struct Number {
var digits: Int
let numbers = 3.1415
}
var n = Number(digits: 12345)
n.digits = 67
print("\(n.digits)")
print("\(n.numbers)")
n.numbers = 8.7
當使用playground運行上述程式時,得到以下結果 -
error: cannot assign to 'numbers' in 'n'
n.numbers = 8.7
它不會將number
重新初始化為8.7
,而是返回一條錯誤消息,指示number
聲明為常量。
懶存儲屬性
Swift 4提供了一個名為“Lazy Stored Property” 的屬性,它不會在第一次初始化變數時計算初始值。 在變數聲明之前使用lazy
修飾符將其作為惰存儲屬性。
使用懶屬性 -
- 延遲對象創建。
- 當屬性依賴於類的其他部分時,會延遲知道。
示例代碼
class sample {
lazy var no = number() // `var` declaration is required.
}
class number {
var name = "Swift 4"
}
var firstsample = sample()
print(firstsample.no.name)
當使用playground運行上述程式時,得到以下結果 -
Swift 4
實例變數
在Objective C中,存儲屬性還有用於備份目的的實例變數,用於存儲在存儲屬性中聲明的值。
Swift 4將這兩個概念集成到一個“存儲屬性”聲明中。 而不是具有相應的實例變數和備份值“存儲屬性”包含通過變數名稱,數據類型和記憶體管理功能在變數屬性的單個位置中定義的所有集成資訊。
計算屬性
不同於存儲值,計算屬性提供了getter
和可選的setter
來間接檢索和設置其他屬性和值。示例代碼 -
class sample {
var no1 = 0.0, no2 = 0.0
var length = 300.0, breadth = 150.0
var middle: (Double, Double) {
get {
return (length / 2, breadth / 2)
}
set(axis){
no1 = axis.0 - (length / 2)
no2 = axis.1 - (breadth / 2)
}
}
}
var result = sample()
print(result.middle)
result.middle = (0.0, 10.0)
print(result.no1)
print(result.no2)
當使用playground運行上述程式時,得到以下結果 -
(150.0, 75.0)
-150.0
-65.0
當計算屬性將新值保留為undefined
時,將為變數設置默認值。
計算屬性為只讀屬性
計算屬性中的只讀屬性被定義為具有getter
,但沒有setter
的屬性。 它始終用於返回值。 變數通過.
運算符訪問。但不能設置為其他值。
示例代碼
class film {
var head = ""
var duration = 0.0
var metaInfo: [String:String] {
return [
"head": self.head,
"duration":"\(self.duration)"
]
}
}
var movie = film()
movie.head = "Swift 4 Properties"
movie.duration = 3.09
print(movie.metaInfo["head"]!)
print(movie.metaInfo["duration"]!)
當使用playground運行上述程式時,得到以下結果 -
Swift 4 Properties
3.09
計算屬性作為屬性觀察者
在Swift 4中觀察和回應屬性值使用屬性觀察者(Property Observers)。 每次設置屬性值時,都會調用屬性觀察者。 除了延遲存儲的屬性,可以通過方法’覆蓋’將屬性觀察者添加到inherited
屬性。
屬性觀察者可以由以下任何一個來定義 -
- 在存儲值之前 - 將要設置
- 存儲新值後 - 確定設置
- 在初始化程式集中設置屬性時,無法調用
didset
觀察者。
參考示例代碼
class Samplepgm {
var counter: Int = 0 {
willSet(newTotal){
print("Total Counter is: \(newTotal)")
}
didSet {
if counter > oldValue {
print("Newly Added Counter \(counter - oldValue)")
}
}
}
}
let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800
當使用playground運行上述程式時,得到以下結果 -
Total Counter is: 100
Newly Added Counter 100
Total Counter is: 800
Newly Added Counter 700
本地和全局變數
聲明局部和全局變數用於計算和觀察屬性。
局部變數 | 全局變數 |
---|---|
在函數,方法或閉包上下文中定義的變數。 | 在函數,方法,閉包或類型上下文之外定義的變數。 |
用於存儲和檢索值。 | 用於存儲和檢索值。 |
存儲的屬性用於獲取和設置值。 | 存儲的屬性用於獲取和設置值。 |
計算屬性也可使用。 | 計算屬性也可使用。 |
類型屬性
屬性在類型定義部分中使用花括弧{}
定義,變數的範圍也先前已定義。 要定義值類型的類型屬性,使用static
關鍵字,對於類類型,使用class
關鍵字。
語法
struct Structname {
static var storedTypeProperty = " "
static var computedTypeProperty: Int {
// return an Int value here
}
}
enum Enumname {
static var storedTypeProperty = " "
static var computedTypeProperty: Int {
// return an Int value here
}
}
class Classname {
class var computedTypeProperty: Int {
// return an Int value here
}
}
查詢和設置屬性
就像實例屬性一樣,查詢類型屬性並使用.
運算符進行設置。 單獨使用類型語法而不是指向實例。示例代碼如下所示 -
struct StudMarks {
static let markCount = 97
static var totalCount = 0
var InternalMarks: Int = 0 {
didSet {
if InternalMarks > StudMarks.markCount {
InternalMarks = StudMarks.markCount
}
if InternalMarks > StudMarks.totalCount {
StudMarks.totalCount = InternalMarks
}
}
}
}
var stud1Mark1 = StudMarks()
var stud1Mark2 = StudMarks()
stud1Mark1.InternalMarks = 98
print(stud1Mark1.InternalMarks)
stud1Mark2.InternalMarks = 87
print(stud1Mark2.InternalMarks)
當使用playground運行上述程式時,得到以下結果 -
97
87