Swift结构体和类详解

一、类和结构体的对比

(一)、类和结构体的相同点
  • 定义存储值的属性;
  • 定义提供功能的方法;
  • 定义下标以使用下标语法提供对其值的访问;
  • 定义初始化器来设置其初始状态;
  • 通过扩展增加新功能;
  • 遵守协议来提供某种标准功能;
(二)、类和结构体的不同点

类具有结构体不具备的其他功能:

  • 继承使一个类可以继承另一个类的特性;
  • 类型转换使你可以在运行时检查和解释类实例的类型;
  • 析构器使类的实例可以释放它已分配的任何资源;
  • 引用计数器允许对一个类实例的多个引用;
(三)、如何选择类和结构体

在应用程序中存储数据和建模行为时,结构和类是很好的选择,但是它们的相似性使得很难正确选择使用哪种数据类型。
考虑以下建议,可以帮助你在向应用程序中添加新数据类型时选择合适的数据类型。

  • 默认情况下使用结构;
  • 在需要Objective-C互操作性时使用类;
  • 当您需要控制正在建模的数据的标识时,请使用类;
  • 使用结构体和协议通过共享实现来采用行为;
    参考资料:
  • 如何选择类和结构体

二、定义语法

类和结构体的定义语法:

struct SomeStructure {
    // structure definition goes here
}
class SomeClass {
    // class definition goes here
}

定义类和结构体的示例:

struct Resolution {
    var width = 0
    var height = 0
}
class VideoMode {
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name: String?
}

二、结构体的全能初始化器

所有结构都有一个自动生成的成员初始化器,可以使用它初始化新结构实例的所有成员属性。

let vga = Resolution(width: 640, height: 480)

与结构不同,类实例不接收默认的全能初始化器。

三、结构体和枚举是值类型

值类型是一种类型,其值在被赋值给变量或常量时被复制,或者在传递给函数时被复制。
Swift中的所有的基本类型:整数、浮点数、布尔、字符串、 数组 和 字典都是值类型,并且在底层的实现是结构体。同时Swift中所有的枚举和结构体也是值类型,这意味着我们创建的任何结构和枚举实例,以及作为它们属性的任何值类型,在代码中传递时始终会被复制。

注意:标准库中定义的集合(如数组,字典和字符串)使用了优化来降低复制时的性能消耗。 这些集合不是立即复制,而是共享内存,其中元素存储在原始实例和任何副本之间。 如果修改了这个集合的其中一个副本,则在修改之前复制元素。 你在代码中看到的行为总是好像立即发生了复制。

let hd = Resolution(width: 1920, height: 1080)
var cinema = hd
cinema.width = 2048
print("cinema is now \(cinema.width) pixels wide")
// Prints "cinema is now 2048 pixels wide"

print("hd is still \(hd.width) pixels wide")
// Prints "hd is still 1920 pixels wide"

上述示例中,首先声明了一个常量hd,将其设置为一个Resolution类型的结构体实例。然后又声明了一个变量cinema,将其设置为hd当前的值。由于Resolution是一个结构体类型,因此会生成该实例的副本,并将新的副本分配给cinema。尽管hdcinema现在有相同的widthheight,但是在内存中它们是两个完全不同的实例。因此当修改cinema中的width属性时,对hd中的width属性并没有影响。它们在内存中的分配如下图所示:

sharedStateStruct_2x.png

同理,枚举也是相同的。

enum CompassPoint {
    case north, south, east, west
    mutating func turnNorth() {
        self = .north
    }
}
var currentDirection = CompassPoint.west
let rememberedDirection = currentDirection
currentDirection.turnNorth()

print("The current direction is \(currentDirection)")
print("The remembered direction is \(rememberedDirection)")
// Prints "The current direction is north"
// Prints "The remembered direction is west"

四、类是引用类型

与值类型不同,引用类型在分配给一个变量或常量,或者传递给函数时不会被拷贝。 不是使用拷贝的对象,而是使用对同一个现有实例对象的引用。

let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0

let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0

print("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
// Prints "The frameRate property of tenEighty is now 30.0"

上述示例中,由于类是引用类型,tenEightyalsoTenEighty都引用相同的VideoMode实例对象。实际上,它们只是同一个实例对象的两个不同名称,如下图所示:

sharedStateClass_2x.png

五、相等性判断

因为类是引用类型,所以多个常量和变量在内存中可能引用的是同一个类的实例对象。 而对于结构和枚举来说情况并非如此,因为它们在分配给常量或变量或传递给函数时总是被复制。
有时可以判断两个常量或变量是否指向同一个类的相同实例对象。 为了实现这一点,Swift提供了两个身份运算符:

  • 相同的 (===)
  • 不完全相同(!==)
    使用这些运算符可以检查两个常量或变量是否引用同一个实例对象:
if tenEighty === alsoTenEighty {
    print("tenEighty and alsoTenEighty refer to the same VideoMode instance.")
}
// Prints "tenEighty and alsoTenEighty refer to the same VideoMode instance."

===并不等同于 =====意味着class类型的两个常量或变量引用完全相同的类实例对象。而==意味着两个实例在值上被认为是相等的或等价的,对于相等的某些适当含义,由类型的设计者定义。
当自定义结构和类时,你有责任确定两个实例相等的条件。 在等价运算符中描述了定义自己的“等于”和“不等于”运算符的实现的过程。 Equivalence Operators

六、指针

如果你熟悉C,C ++或Objective-C,你可能知道这些语言都使用指针来引用内存中的地址。 Swift中的常量或变量对某个引用类型的实例的引用,类似于C中的指针,但是它不是指向内存中地址的直接指针,并且也不需要你使用星号(*)来指明正在创建一个引用。 相反,这些引用的定义与Swift中的任何其他常量或变量一样。 标准库提供了指针和缓冲区类型,如果需要直接与指针交互,可以使用这些类型- 请参阅手动内存管理

七、其他专题模块

Swift 4.2 基础专题详解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,880评论 2 9
  • Swift语法基础(五)-- (类和结构体、属性、方法) 本章将会介绍 类和结构体对比结构体和枚举是值类型类是引用...
    寒桥阅读 1,103评论 0 1
  • 人一生会遇到很多人,有些人喜欢在你人生中来来去去,走了又来,来了又走,也有一些人出现在你的人生历程中就为了给你一个...
    付小悦阅读 185评论 0 0
  • 今天的文章题目不好取,母爱的范围太大也不知道怎么样概括。在我的生长环境中,接收到的母爱次数比父爱多,这与我的家庭...
    晴天小站阅读 263评论 2 0
  • 我们注重的不应该是软件本身, 而是其中生活积累沉淀后的思想,持续关注你的大脑,是在归纳、整理、纠错,更是优化思绪的...
    菜五阅读 203评论 0 1