专栏首页韦弦的偶尔分享100 Days of SwiftUI —— Day 9:结构体(下)

100 Days of SwiftUI —— Day 9:结构体(下)

如您所见,结构使我们可以合并各个数据片段以创建新内容,然后附加方法,以便我们可以操纵该数据。

今天,您将学习结构的一些更高级的功能,这些功能使它们更强大,包括访问控制静态属性惰性。是的,惰性——比尔·盖茨曾经说过:"我选择一个懒惰的人去做艰苦的工作,因为一个懒惰的人会找到一种简单的方法来做这件事。(I choose a lazy person to do a hard job, Because a lazy person will find an easy way to do it.)''如您所见,在Swift中,惰性是一项重要的性能优化。

提醒一下,所有这些东西都在SwiftUI中得到了广泛使用,因此值得花些时间来掌握它们,因为它们将从我们的第一个项目开始就被使用。

今天,您有6个一分钟的视频可供观看,并且像往常一样,完成每个视频后,都会进行一次简短的测试,以帮助您了解所教的内容。

1. 初始化器 Initializerstest

初始化是特殊的方法,提供了创建结构体的不同方法。默认情况下,所有结构体都带有一个默认的初始化器,称为成员初始化器(memberwise initializer)——这要求您在创建结构体时为每个属性提供一个值。

如果我们创建具有一个属性的User结构体,则可以看到以下内容:

struct User {
    var username: String
}

创建这些结构体之一时,必须提供用户名:

var user = User(username: "twostraws")

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

struct User {
    var username: String

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

您不必在初始化器之前编写func,但需要确保在初始化结束之前所有属性都具有一个值。

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

var user = User()
user.username = "twostraws"

2. 引用当前实例 Referring to the current instancetest

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

例如,如果您创建一个具有name属性的Person结构体,然后尝试编写一个接受name参数的初始化器,那么self可以帮助您区分该属性和参数—— self.name是指该属性,而name是指该属性参数。 代码如下:

struct Person {
    var name: String

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

3. 懒加载属性 Lazy propertiestest

作为性能优化,Swift允许您仅在需要时才创建一些属性。例如,考虑以下FamilyTree结构体——并没有做很多事,但是从理论上讲,为某人创建家谱需要很长时间:

struct FamilyTree {
    init() {
        print("Creating family tree!")
    }
}

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

struct Person {
    var name: String
    var familyTree = FamilyTree()

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

var ed = Person(name: "Ed")

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

lazy var familyTree = FamilyTree()

因此,如果您想看到“Creating family tree!”消息,您需要至少访问一次该属性:

ed.familyTree

4. 静态属性和方法 Static properties and methodstest

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

struct Student {
    var name: String

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

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

您也可以要求Swift在结构体的所有实例之间共享特定的属性和方法,方法是将它们声明为静态的(static)

要尝试此操作,我们将向Student结构体添加一个静态属性,以存储班上有多少学生。每次创建新学生时,我们都会向其中添加一个:

struct Student {
    static var classSize = 0
    var name: String

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

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

print(Student.classSize)

5. 访问控制 Access controltest

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

我们可以创建一个具有id属性的Person结构体,以存储其社会保险号:

struct Person {
    var id: String

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

let ed = Person(id: "12345")

创建该人后,我们可以将其id设为私有,这样您就无法从struct外部读取它——尝试编写·ed.id·根本行不通。

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

struct Person {
    private var id: String

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

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

truct Person {
    private var id: String

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

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

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

(PS Swift的访问控制关键字有如下五种):

关键字

简单描述

open

公开权限, 最高的权限, 可以被其他模块访问, 继承及复写。

public

公有访问权限,类或者类的公有属性或者公有方法可以从文件或者模块的任何地方进行访问。无法在其他模块被复写方法/属性或被继承。

fileprivate

可以在同一个物理文件中访问。如果超出该物理文件,属性和方法就不能被访问。

private

私有访问权限,被private修饰的类或者类的属性或方法可以在同一个物理文件中的同一个类型(包含extension)访问。如果超出该物理文件或不属于同一类型,那么有着private访问权限的属性和方法就不能被访问。

internal

Swift默认访问权限,模块内部可以访问,超出模块内部就不能被访问了。

6. 结构体: 总结 Structs summarytest

您已经完成了本系列第七部分,因此,让我们总结一下:

1、您可以使用结构体创建自己的类型,这些结构体可以具有自己的属性和方法。 2、您可以使用存储属性或使用计算属性即时计算值。 3、如果要在方法内部更改属性,则必须将其标记为mutating。 4、初始化器是创建结构体的特殊方法。默认情况下,您将获得一个成员初始化器,但是如果创建自己的初始化器,则必须为所有属性赋予一个值。 5、使用self常量可以在方法内部引用结构体的当前实例。 6、lazy关键字告诉Swift仅在首次使用属性时才创建属性。 7、您可以使用static关键字在结构体的所有实例之间共享属性和方法。 8、访问控制使您可以限制哪些属性和方法的代码是可以外部使用的。

这是Swift的另一个重要主题——干得好!现在,做一些聪明的事情,并在网上发布进度:它迫使您用自己的话来写这些事情,并鼓励您继续明天。

< Previous: 结构体(上)

Next: 类 >

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Swift入门:属性

    结构体和类(统称为“类型”)可以有自己的变量和常量,这些称为属性。这些方法允许您将值附加到类型以唯一地表示它们,但因为类型也可以有方法,所以您可以让它们根据自己...

    韦弦zhy
  • Swift 5.1 中引入的部分有用的新特性

    Swift 5.1现在已经正式发布,尽管只是次要版本,它包含了大量的更改和改进。从基本的新功能,例如模块稳定性(使SDK供应商可以交付预编译的Swift框架)到...

    韦弦zhy
  • 100 Days of SwiftUI —— Day 8:结构体(上)

    我知道你们中的某些人可能会热衷于今天的Swift新学习,但请坚持:您刚刚完成了关于闭包的学习,那是一个困难的话题。然后您今天还能回来继续学习更多的内容,认真地说...

    韦弦zhy
  • 人类的性取向是先天还是后天形成?加州理工学院David Anderson教授用脑成像技术揭示答案

    镁客网
  • Nature 神经科学 | 科学家首次发现使用动态贝叶斯推理的脑区

    想象一下,房间里灯关着,黑漆漆的,你刚睡醒,想出门去。你张着双臂摸索着朝门走去,这时你会凭记忆来预测自己离门的距离,并以此决定自己脚下的步子。假如你不小心碰到了...

    新智元
  • Day9面向对象编程2/2

    继承和多态 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class...

    林清猫耳
  • Vue学习笔记之Vue的面向对象

    上面这种写法跟传统的面向对象语言(比如 C++ 和 Java)差异很大,很容易让新学习这门语言的程序员感到困惑。

    Jetpropelledsnake21
  • MyBatis笔记一:GettingStart

    lwen
  • shiro权限控制(一):shiro介绍以及整合SSM框架

      shiro安全框架是目前为止作为登录注册最常用的框架,因为它十分的强大简单,提供了认证、授权、加密和会话管理等功能 。  shiro能做什么? 认证:验...

    生活创客
  • JS判断字符串长度(英文占1个字符,中文汉字占2个字符)

    用户1065635

扫码关注云+社区

领取腾讯云代金券