Swift 5.1 (9) - 结构体和类

级别: ★☆☆☆☆
标签:「iOS」「Swift 5.1」「结构体」「类」「mutating」
作者: 沐灵洛
审校: QiShare团队


结构体和类

结构体和类是多功能的,灵活的结构,是程序中代码的构建块。我们可以使用与定义常量,变量和函数相同的语法来定义属性和方法,为我们的结构体和类添加功能。
Swift中我们为自定义的结构体和类不需要创建单独的.h和.m文件。而是在单个文件中定义结构体或类即可,并且Swift会提供额外的接口,自动让类或结构体在其他代码中可用。

比较结构体和类

在Swift中,结构体和类有许多相像的地方。

  • 定义存储值的属性
  • 定义提供功能的方法
  • 定义下标以使用下标语法提供对其值进行访问
  • 定义初始化方法以设置其初始状态
  • 可以被扩展 extend,在函数的默认实现的基础上可以扩展其功能。
  • 可以遵守协议以提供某种标准功能

同时,类具有结构体所没有的附加功能:

  • 继承:一个类能够继承另一个类的特性。
  • 类型转换:在运行时检查和解释类的实例对象所属类型。
  • 析构函数(Deinitializers):允许类的实例对象释放它已分配的任何资源。
  • 引用计数:允许对类实例进行多个引用。

语法定义

结构和类具有相似的定义语法。使用struct关键字定义一个结构体。使用class关键字定义类。

struct SomeStructure {
}
class SomeClass {
}

结构体和类的实例

结构和类构建新实例的最简单的初始化语法:使用类或结构体的类型名称,后跟空括号。

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

属性访问

使用.语法进行结构体和类的属性的访问

let width = someResolution.width
let width = someVideoMode.resolution.width 

使用.语法为属性赋新值

someResolution.width = 250
someVideoMode.resolution.width  = 255

结构体类型的成员初始化方法

所有结构体都有一个自动生成的初始化方法。我们可以使用这个自动生成的初始化方法初始化一个新的实例对象,并根据初始化方法的参数(结构体中定义的属性名称),设置成员的属性。

let someResolution = Resolution(width: 33, height: 77)

与结构体不同,类没有默认的成员初始化方法。

结构体和枚举是值类型

类似Swift中的整数,浮点数,布尔值,字符串,数组和字典,都是值类型的,并且这些类型在Swift中的实现都是基于结构体的。故所有结构体和枚举值类型都是值类型。这意味着我们创建的任何结构体和枚举实例以及作为它们属性的任何值类型,在代码中传递时始终会被复制。
注意:标准库定义的集合,如:数组,字典和字符串使用优化来降低复制的性能成本。这些集合类型不是立即复制,而是共享内存,其元素存储在原始实例和任何副本之间。如果需要修改集合的其中一个副本,则会在修改之前复制集合中的所有元素。但是我们在代码中看到的好像总是立即发生了复制。

let someResolution = Resolution(width: 33, height: 77)
var myResolution = someResolution

在这个赋值的过程中,由于Resolution是值类型的,所以首先会生成someResolution实例的副本并将此副本赋值给myResolution。此时someResolutionmyResolution具有相同的宽度和高度,但是却是两个不同的实例。

myResolution.width = 255

someResolutionmyResolution是两个单独的实例,所以修改副本myResolution的属性width,并不会影响someResolutionwidth
枚举类型也是值类型,具有和结构体一样的赋值特性:复制

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

print("当前的方向,被改变后 \(currentDirection)")//!< 当前的方向,被改变后 north
print("保存的方向 \(rememberedDirection)")//!< 保存的方向 west

使用mutating关键字放在枚举或结构体中所定义方法的func关键字之前,使得该方法可以在方法中修改枚举或结构体的属性。
currentDirection赋值给rememberedDirection时,rememberedDirection拥有的是currentDirection实例的副本。此后更改currentDirection的值不会影响存储在rememberedDirection中值。因为彼此独立。

类是引用类型的

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

let tenEighty = VideoMode()
tenEighty.resolution = someResolution
tenEighty.interlaced = true
tenEighty.name = "视频模式"
tenEighty.frameRate = 25.0
//赋值给新的实例对象
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
print(tenEighty.frameRate,alsoTenEighty.frameRate)
//!< tenEighty.frameRate:30.0 alsoTenEighty.frameRate:30

身份运算符

参考swift 5.1基础(二)运算符讲解。

指针

Swift中引用某个引用类型的实例作为常量或变量时,类似于C中的指针,但它不是指向内存中地址的直接指针(不是直接寻址),并且不需要编写星号*来指示你正在创建一个引用对象。相反,这些引用的定义与Swift中的任何其他常量或变量一样。
另:Swift标准库提供指针和缓冲类型,如果需要直接与指针交互,可以使用它们 手动内存管理

参考资料:
swift 5.1官方编程指南


推荐文章:
Swift 实现一个兼容iOS、tvOS、OSX的抽象层
iOS Password AutoFill
iOS 给UILabel添加点击事件
用SwiftUI给视图添加动画
用SwiftUI写一个简单页面
Swift 5.1 (7) - 闭包
iOS App启动优化(三)—— 自己做一个工具监控App的启动耗时
iOS App启动优化(二)—— 使用“Time Profiler”工具监控App的启动耗时
iOS App启动优化(一)—— 了解App的启动流程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容