文章目录
初始化器
初始化器是一种特殊方法,可提供创建结构体的不同方式。所有结构体都默认带有一个初始化器,称为成员初始化器- 它会要求您在创建结构体时为每个属性提供一个值。
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。
- 访问控制允许您限制哪些代码可以使用属性和方法。