Swift 属性

Swift 属性

我们可以定义属性来将值与类、结构和枚举关联起来。在Swift中,我们可以定义两种类型的属性,即存储属性和计算属性。存储属性将变量和常量值存储为类属性。而计算属性根据特定值计算值。我们可以在类、结构和枚举中定义计算属性;但是,存储属性只能在类和结构中定义。

特定类型的实例,包括结构、类和枚举,与类型中定义的所有属性关联。但是,属性也可以与类型本身关联,而不是实例。这种属性被称为类型属性。

在本教程的这一部分,我们将讨论各种类型的Swift属性,如存储属性和计算属性。

存储属性

简单地说,存储属性是作为特定类或结构实例的一部分定义的常量或变量。存储属性可以是常量(使用let关键字定义)或变量(使用var关键字定义)。我们可以在声明存储属性时为其提供默认值。然而,在初始化类或结构时,我们可以修改存储属性的默认值。

让我们来考虑下面的示例,它定义了一个名为Person的类。它包含变量存储属性name和age。每个人都有一个默认的姓名和年龄,可以在初始化时更改。

class Person{
    var name:String = "Anonymous"
    var age:Int = 20
    init() {

    }
    init(name:String, age:Int) {
        self.name = name
        self.age = age
    }
}

现在,如果我们创建一个Person类的实例并将其标记为常量,它不会影响我们存储的变量属性,因为我们仍然可以改变它们的值,如下所示。

var person = Person()
person.name = "John"
person.age = 23
debugPrint(person.name + " " + person.age.description)

这将在控制台上打印以下输出。

"John 23"

然而,对于结构体类型来说情况并非如此,因为结构体包含值类型。如果我们将一个结构体标记为常量,尽管属性是可变的,但我们无法更改它的所有存储属性。考虑以下示例。

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)

惰性存储属性

惰性存储属性在系统中直到第一次使用它之前不占用内存。换句话说,惰性存储属性的值直到第一次访问它之前不会被计算出来。我们可以在Swift中使用”lazy”关键字将一个属性定义为惰性。然而,我们不能将惰性存储属性定义为常量,因为它的值可能在声明时无法检索到。

惰性属性在以下情况下非常有用:属性的值取决于外部因素,并且需要在这些值知道之后计算。如果属性在初始化时需要进行复杂的设置,并且在第一次访问值之前不需要使用,我们也可以使用惰性属性。

考虑以下示例,其中定义了类Employee和Department之间的关系。在这里,类Department包含一个类型为Employee的惰性存储属性,表示当与Employee相关联时将创建Employee属性。

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

计算属性

我们可以将计算属性定义为类、结构体和枚举类型的实例的一部分。与存储属性不同,计算属性不存储值。相反,它们提供了getter和可选的setter来间接地检索和设置其他属性和值。

示例1

考虑下面的示例,定义了一个名为Person的类。Person有一个姓名、年龄和给世界的特殊信息。姓名和年龄是存储属性,而信息是一个计算属性,其值基于Person的姓名和年龄确定。

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 类中包含了诸如名字、年龄和希望的节日之类的存储属性。然而,消息是通过计算得出的。因此,它是一个计算属性,其值基于一个人的名字、年龄和希望的节日来确定将要传递的消息。

var person = Person(name: "John", age: 23, festival: "Diwali")
debugPrint(person.message)

如果我们打印这个人的消息,下面的消息将被打印到控制台。

"Hi I am John, and I am 23 years old. I wish you all a very Happy Diwali"

示例2:

考虑以下示例,其中Circle类包含两个属性。 radius是存储属性,而area则是根据圆的半径计算出来的。

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)")

它在控制台上打印以下内容。

"Area of circle is 31400.0"

示例 3:

让我们扩展示例2中定义的Circle类,并计算给定圆的面积的半径。

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。

var circle = Circle(radius: 100)
circle.area = 31400
debugPrint("Radius of Circle is \(circle.radius)")

根据修改后的面积,将打印圆的新半径,如下所示。

"Radius of Circle is 316.2287731100305"

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程