IOS Swift 从入门到精通: 结构体的访问控制、静态属性和惰性

文章目录

初始化器

初始化器是一种特殊方法,可提供创建结构体的不同方式。所有结构体都默认带有一个初始化器,称为成员初始化器- 它会要求您在创建结构体时为每个属性提供一个值。

User如果我们创建一个具有一个属性的结构,你就会看到这一点:

swift 复制代码
struct User {
    var username: String
}

当我们创建其中一个结构时,我们必须提供一个用户名:

swift 复制代码
var user = User(username: "twostraws")

我们可以提供自己的初始化程序来替换默认的初始化程序。例如,我们可能希望将所有新用户创建为"匿名"并打印一条消息,如下所示:

swift 复制代码
struct User {
    var username: String

    init() {
        username = "Anonymous"
        print("Creating a new user!")
    }
}

您不需要在初始化程序之前写入func,但是您需要确保在初始化程序结束之前所有属性都有一个值。

现在我们的初始化程序不接受任何参数,我们需要像这样创建结构:

swift 复制代码
var user = User()
user.username = "twostraws"

引用当前实例

在方法内部,您会得到一个名为 的特殊常量self,它指向当前正在使用的结构的任何实例。self当您创建具有与属性相同参数名称的初始化程序时,此值特别有用。

例如,如果您创建一个具有属性Person的结构体name,然后尝试编写一个接受name参数的初始化程序,self可以帮助您区分属性和参数------ self.name引用属性,而引用name参数。

代码如下:

swift 复制代码
struct Person {
    var name: String

    init(name: String) {
        print("\(name) was born!")
        self.name = name
    }
}

惰性属性

作为一项性能优化,Swift 允许您仅在需要时创建某些属性。例如,考虑这个FamilyTree结构体------它没有太多作用,但理论上为某人创建家谱需要很长时间:

swift 复制代码
struct FamilyTree {
    init() {
        print("Creating family tree!")
    }
}

我们可以将该FamilyTree结构用作结构内的属性Person,如下所示:

swift 复制代码
struct Person {
    var name: String
    var familyTree = FamilyTree()

    init(name: String) {
        self.name = name
    }
}
swift 复制代码
var ed = Person(name: "Ed")

但是如果我们并不总是需要某个人的家谱呢?如果我们将关键字添加lazy到属性中familyTree,那么 Swift 将仅FamilyTree在第一次访问时创建结构体:

swift 复制代码
lazy var familyTree = FamilyTree()

因此,如果您想看到"创建家谱!"消息,您需要至少访问该属性一次:

swift 复制代码
ed.familyTree

静态属性和方法

到目前为止,我们创建的所有属性和方法都属于结构体的单独实例,这意味着,如果我们有一个Student结构体,我们可以创建多个学生实例,每个实例都有自己的属性和方法:

swift 复制代码
struct Student {
    var name: String

    init(name: String) {
        self.name = name
    }
}

let ed = Student(name: "Ed")
let taylor = Student(name: "Taylor")

您还可以通过将特定属性和方法声明为静态,要求 Swift 在结构的所有实例之间共享它们。

为了尝试这一点,我们将向Student结构体添加一个静态属性来存储班级中有多少名学生。每次我们创建一个新学生时,我们都会向其中添加一个:

swift 复制代码
struct Student {
    static var classSize = 0
    var name: String

    init(name: String) {
        self.name = name
        Student.classSize += 1
    }
}

因为该classSize属性属于结构本身而不是结构的实例,所以我们需要使用以下方法来读取它

swift 复制代码
Student.classSize:

print(Student.classSize)

访问控制

访问控制可让您限制哪些代码可以使用属性和方法。这很重要,因为您可能希望阻止人们直接读取属性。

我们可以创建一个Person具有id属性的结构来存储他们的社会安全号码:

swift 复制代码
struct Person {
    var id: String

    init(id: String) {
        self.id = id
    }
}

let ed = Person(id: "12345")

一旦创建了该人,我们可以将其设为id私密,这样你就无法从结构外部读取它------尝试写入ed.id根本行不通。

只需使用private关键字,如下所示:

swift 复制代码
struct Person {
    private var id: String

    init(id: String) {
        self.id = id
    }
}

现在只有内部方法Person可以读取该id属性。例如:

swift 复制代码
struct Person {
    private var id: String

    init(id: String) {
        self.id = id
    }

    func identify() -> String {
        return "My social security number is \(id)"
    }
}

另一个常见选项是public,它允许所有其他代码使用该属性或方法。

总结

总结一下:

  • 您可以使用结构创建自己的类型,它们可以具有自己的属性和方法。
  • 您可以使用存储的属性或使用计算属性来动态计算值。
  • 如果您想更改方法内的属性,则必须将其标记为mutating。
  • 初始化器是创建结构体的特殊方法。默认情况下,您会获得成员初始化器,但如果您创建自己的初始化器,则必须为所有属性赋予值。
  • 使用self常量来引用方法内部结构的当前实例。
  • 该lazy关键字告诉 Swift 仅在第一次使用时创建属性。
  • 您可以使用关键字在结构的所有实例之间共享属性和方法static。
  • 访问控制允许您限制哪些代码可以使用属性和方法。
相关推荐
2401_8574396935 分钟前
SSM 架构下 Vue 电脑测评系统:为电脑性能评估赋能
开发语言·php
SoraLuna1 小时前
「Mac畅玩鸿蒙与硬件47」UI互动应用篇24 - 虚拟音乐控制台
开发语言·macos·ui·华为·harmonyos
xlsw_1 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
Dream_Snowar2 小时前
速通Python 第三节
开发语言·python
高山我梦口香糖3 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
信号处理学渣3 小时前
matlab画图,选择性显示legend标签
开发语言·matlab
红龙创客3 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
jasmine s4 小时前
Pandas
开发语言·python
biomooc4 小时前
R 语言 | 绘图的文字格式(绘制上标、下标、斜体、文字标注等)
开发语言·r语言
骇客野人4 小时前
【JAVA】JAVA接口公共返回体ResponseData封装
java·开发语言