swift 类和结构体

2023-11-22 09:10:51 浏览数 (2)

定义

  • 类定义(通过关键字class),结构体定义(通过关键字struct)
代码语言:javascript复制
class Student: NSObject {
    var name = ""
    var age = 0
}

struct Teacher {
    var name = ""
    var age = 0
}
  • 类和结构体实例
代码语言:javascript复制
let student = Student()
let teacher = Teacher()
  • 所有结构体会自动生成一个构造器,用于初始化结构体中的属性(类没有此功能)
代码语言:javascript复制
let ter = Teacher(name: "teacher", age: 30)
  • 属性访问
代码语言:javascript复制
student.name = "student"
teacher.name = "teacher"
print(student.name)
print(teacher.name)

结构体是值类型

值类型被赋予给一个变量、常量或被传递给一个函数的时,其值会被拷贝(在 Swift 中,所有的基本类型:整数、浮点数、布尔值、字符串、数组和字典,都是值类型

代码语言:javascript复制
struct Teacher {
    var name = ""
    var age = 0
}

let ter = Teacher(name: "teacher", age: 30)

//因为Teacher是一个结构体,所以ter1的值其实是ter的一个拷贝副本,而不是ter本身。尽管ter和ter1有着相同的name和age,但其实它们是两个完全不同的实例
var ter1 = ter

ter1.name = "good teacher"

//通过log证明ter和ter1其中任何一个修改都不会影响另一个
print(ter.name)    //teacher
print(ter1.name)  //good teacher

类是引用类型

引用类型在被赋予到一个变量、常量或者被传递到一个函数时,其值不会被拷贝。因此,引用的是已存在的实例本身而不是其拷贝

代码语言:javascript复制
class Student: NSObject {
    var name = ""
    var age = 0
}

let stu = Student()
stu.name = "good student"

//因为类是引用类型,所以stu1和stu实际上引用的是相同的Student实例
let stu1 = stu

stu1.name = "bad student"

print(stu.name)    //bad student
print(stu1.name)  //bad student

注意: stustu1被声明为常量而不是变量。但是,依然可以改变stu.namestu1.name,因为stustu1这两个常量的值并未改变。它们并不存储这个Student实例,而是指向Student的实例。所以,改变的是被引用的Studentname属性,而不是引用Student的常量的值

恒等运算符

因为类是引用类型,有可能有多个常量和变量同时指向同一个类的实例。(对于结构体和枚举来说,这并不成立。因为它们作为值类型,在被赋予到常量、变量或者传递到函数时,其值总是会被拷贝。)

能够判定两个常量或者变量是否引用同一个类实例,使用===!==

代码语言:javascript复制
    if stu === stu1 {
          print("same Student instance")
    }

类和结构体对比

Swift 中类和结构体有很多共同点
  • 定义属性用于存储值
  • 定义方法用于提供功能
  • 定义下标可以使用下标语法来访问实例所包含的值
  • 定义构造器用于生成初始化值
  • 通过扩展可以增加默认实现的功能
  • 通过协议可以提供某种标准功能
与结构体相比,类还有如下的附加功能
  • 继承允许一个类继承另一个类的特征
  • 类型转换允许在运行时检查和解释一个类实例的类型
  • 析构器允许一个类实例释放任何其所被分配的资源
  • 引用计数允许对一个类的多次引用
注意

结构体总是通过被复制的方式在代码中传递,不使用引用计数

0 人点赞