Swift 屬性
我們可以定義屬性來將值與類、結構和枚舉關聯起來。愛掏網 - it200.com在Swift中,我們可以定義兩種類型的屬性,即存儲屬性和計算屬性。愛掏網 - it200.com存儲屬性將變量和常量值存儲為類屬性。愛掏網 - it200.com而計算屬性根據特定值計算值。愛掏網 - it200.com我們可以在類、結構和枚舉中定義計算屬性;但是,存儲屬性只能在類和結構中定義。愛掏網 - it200.com
特定類型的實例,包括結構、類和枚舉,與類型中定義的所有屬性關聯。愛掏網 - it200.com但是,屬性也可以與類型本身關聯,而不是實例。愛掏網 - it200.com這種屬性被稱為類型屬性。愛掏網 - it200.com
在本教程的這一部分,我們將討論各種類型的Swift屬性,如存儲屬性和計算屬性。愛掏網 - it200.com
存儲屬性
簡單地說,存儲屬性是作為特定類或結構實例的一部分定義的常量或變量。愛掏網 - it200.com存儲屬性可以是常量(使用let關鍵字定義)或變量(使用var關鍵字定義)。愛掏網 - it200.com我們可以在聲明存儲屬性時為其提供默認值。愛掏網 - it200.com然而,在初始化類或結構時,我們可以修改存儲屬性的默認值。愛掏網 - it200.com
讓我們來考慮下面的示例,它定義了一個名為Person的類。愛掏網 - it200.com它包含變量存儲屬性name和age。愛掏網 - it200.com每個人都有一個默認的姓名和年齡,可以在初始化時更改。愛掏網 - it200.com
class Person{
var name:String = "Anonymous"
var age:Int = 20
init() {
}
init(name:String, age:Int) {
self.name = name
self.age = age
}
}
現在,如果我們創建一個Person類的實例并將其標記為常量,它不會影響我們存儲的變量屬性,因為我們仍然可以改變它們的值,如下所示。愛掏網 - it200.com
var person = Person()
person.name = "John"
person.age = 23
debugPrint(person.name + " " + person.age.description)
這將在控制臺上打印以下輸出。愛掏網 - it200.com
"John 23"
然而,對于結構體類型來說情況并非如此,因為結構體包含值類型。愛掏網 - it200.com如果我們將一個結構體標記為常量,盡管屬性是可變的,但我們無法更改它的所有存儲屬性。愛掏網 - it200.com考慮以下示例。愛掏網 - it200.com
struct Person{
var name:String = "Anonymous"
var age:Int = 20
}
let person = Person()
person.name = "John" // will give compiler error as "Cannot assign to property: 'person' is a 'let' constant"
person.age = 23
debugPrint(person.name + " " + person.age.description)
惰性存儲屬性
惰性存儲屬性在系統中直到第一次使用它之前不占用內存。愛掏網 - it200.com換句話說,惰性存儲屬性的值直到第一次訪問它之前不會被計算出來。愛掏網 - it200.com我們可以在Swift中使用”lazy”關鍵字將一個屬性定義為惰性。愛掏網 - it200.com然而,我們不能將惰性存儲屬性定義為常量,因為它的值可能在聲明時無法檢索到。愛掏網 - it200.com
惰性屬性在以下情況下非常有用:屬性的值取決于外部因素,并且需要在這些值知道之后計算。愛掏網 - it200.com如果屬性在初始化時需要進行復雜的設置,并且在第一次訪問值之前不需要使用,我們也可以使用惰性屬性。愛掏網 - it200.com
考慮以下示例,其中定義了類Employee和Department之間的關系。愛掏網 - it200.com在這里,類Department包含一個類型為Employee的惰性存儲屬性,表示當與Employee相關聯時將創建Employee屬性。愛掏網 - it200.com
import Foundation
class Employee{
var name:String
var id:Int
var salary:Double
var department:Department?
init(name:String,id:Int,salary:Double) {
self.name = name
self.id = id
self.salary = salary
}
}
class Department{
var name:String = "IT"
lazy var employees = Array()
}
var dep = Department()
dep.name = "CS"
var emp = Employee(name: "John", id: 102, salary: 25000.0)
emp.department = dep
dep.employees.append(emp) //the employee property will be created now
計算屬性
我們可以將計算屬性定義為類、結構體和枚舉類型的實例的一部分。愛掏網 - it200.com與存儲屬性不同,計算屬性不存儲值。愛掏網 - it200.com相反,它們提供了getter和可選的setter來間接地檢索和設置其他屬性和值。愛掏網 - it200.com
示例1
考慮下面的示例,定義了一個名為Person的類。愛掏網 - it200.comPerson有一個姓名、年齡和給世界的特殊信息。愛掏網 - it200.com姓名和年齡是存儲屬性,而信息是一個計算屬性,其值基于Person的姓名和年齡確定。愛掏網 - it200.com
class Person{
var name:String
var age:Int
var festival:String
var message: String{
return "Hi I am \(name), and I am \(age) years old. I wish you all a very Happy \(festival)"
}
init(name:String,age:Int,festival:String) {
self.name = name
self.age = age
self.festival = festival
}
}
Person 類中包含了諸如名字、年齡和希望的節日之類的存儲屬性。愛掏網 - it200.com然而,消息是通過計算得出的。愛掏網 - it200.com因此,它是一個計算屬性,其值基于一個人的名字、年齡和希望的節日來確定將要傳遞的消息。愛掏網 - it200.com
var person = Person(name: "John", age: 23, festival: "Diwali")
debugPrint(person.message)
如果我們打印這個人的消息,下面的消息將被打印到控制臺。愛掏網 - it200.com
"Hi I am John, and I am 23 years old. I wish you all a very Happy Diwali"
示例2:
考慮以下示例,其中Circle類包含兩個屬性。愛掏網 - it200.com radius是存儲屬性,而area則是根據圓的半徑計算出來的。愛掏網 - it200.com
class Circle{
var radius:Double
var area:Double{
get{
return 3.14 * radius * radius
}
}
init(radius:Double) {
self.radius = radius
}
}
var circle = Circle(radius: 100)
debugPrint("Area of circle is \(circle.area)")
它在控制臺上打印以下內容。愛掏網 - it200.com
"Area of circle is 31400.0"
示例 3:
讓我們擴展示例2中定義的Circle類,并計算給定圓的面積的半徑。愛掏網 - it200.com
class Circle{
var radius:Double
var area:Double{
get{
return 3.14 * radius * radius
}
set(newValue){
radius = sqrt(newValue/3.14)
}
}
init(radius:Double) {
self.radius = radius
}
}
如果我們為圓的面積分配某個值,它將根據面積計算半徑,并將其分配給存儲屬性radius。愛掏網 - it200.com
var circle = Circle(radius: 100)
circle.area = 31400
debugPrint("Radius of Circle is \(circle.radius)")
根據修改后的面積,將打印圓的新半徑,如下所示。愛掏網 - it200.com
"Radius of Circle is 316.2287731100305"