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。
  • 访问控制允许您限制哪些代码可以使用属性和方法。
相关推荐
我是陈泽7 分钟前
一行 Python 代码能实现什么丧心病狂的功能?圣诞树源代码
开发语言·python·程序员·编程·python教程·python学习·python教学
优雅的小武先生17 分钟前
QT中的按钮控件和comboBox控件和spinBox控件无法点击的bug
开发语言·qt·bug
虽千万人 吾往矣23 分钟前
golang gorm
开发语言·数据库·后端·tcp/ip·golang
创作小达人26 分钟前
家政服务|基于springBoot的家政服务平台设计与实现(附项目源码+论文+数据库)
开发语言·python
郭二哈29 分钟前
C++——list
开发语言·c++·list
杨荧30 分钟前
【JAVA开源】基于Vue和SpringBoot的洗衣店订单管理系统
java·开发语言·vue.js·spring boot·spring cloud·开源
ZPC821036 分钟前
Python使用matplotlib绘制图形大全(曲线图、条形图、饼图等)
开发语言·python·matplotlib
missmisslulu38 分钟前
电容笔值得买吗?2024精选盘点推荐五大惊艳平替电容笔!
学习·ios·电脑·平板
镜花照无眠38 分钟前
Python爬虫使用实例-mdrama
开发语言·爬虫·python
aaasssdddd961 小时前
python和c
c语言·开发语言·python