Swift5.5学习笔记八:结构和类(Stuctures And Classes)

//结构和类
//结构和类是通用的、灵活的结构,它们成为程序代码的代码块。
//您可以使用与定义常量、变量和函数相同的语法来定义属性和方法以向结构和类添加功能。

//一、结构和类的比较
//Swift 中的结构和类有很多共同点。
//相同点:
//定义存储值的属性
//定义提供功能的方法
//定义下标以使用下表语法访问它们的值
//定义初始值设定项以设置其初始状态
//扩展默认实现之外的功能
//提供符合协议的标准功能

//另外,类还具有一些结构不具备的功能:
//一个类可以继承另外一个类特性的能力
//类型转换使您能够在运行时检查和解释类的实例的类型
//析构器使类的实例能够释放它分配的任何资源
//引用计数允许对一个类实例有多个引用

//1.定义语法
//结构和类具有相似的定义语法。用struct关键字引入结构,用关键字class引入类。两者都将整个定义放在一对大括号中:

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

//备注:每当你定义一个新的结构或类时,你就定义了一个新的Swift类型。
//使用大驼峰(UpperCamelCase)命名类型(例如SomeStructure和SomeClass)以匹配标准Swift类型(例如String, Int, 和Bool)的大小写。
//使用小驼峰(lowerCamelCase)命名属性和方法(例如frameRate和incrementCount)以将它们与类型名称区分开来。

//这是结构定义和类定义的示例:

struct Resolution {
    var width = 0
    var height = 0
}


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

//上面的示例定义了一个名为Resolution的新结构,用于描述基于像素的显示分辨率。
//这个结构有两个存储属性,称为width和height。存储属性是常量或变量作为结构或类的一部分捆绑在一起存储的。这两个Int类型属性的处事之为0。

//上面的示例还定义了一个名为VideoMode的新类,用于描述视频显示的特定视频模式。
//这个类有四个存储变量属性。第一个 resolution用一个Resolution结构实例初始化,它推断属性类型为Resolution。
//其他三个属性,VideoMode实例将属性interlaced设置false、播放帧速率frameRate设置为0.0,name是一个可选String值来初始化,name属性是一个可选类型自动被赋予一个默认值nil。

//2.结构和类实例
//创建实例的语法对于结构和类都非常相似:

let someResolution = Resolution()
let someVideoMode = VideoMode()

//3.访问属性
//您可以使用点语法访问实例的属性。在点语法中,您在实例名称后立即写入属性名称,用句点(.)分隔,不带任何空格:

print("The width of someResolution is \(someResolution.width)")
// Prints "The width of someResolution is 0"

//在本例中,someResolution.width引用someResolution的width属性,并返回其默认初始值0。

//您可以深入到子属性,例如VideoMode的resolution属性的resolution属性中的width属性:

print("The width of someVideoMode is \(someVideoMode.resolution.width)")
// Prints "The width of someVideoMode is 0"

//您还可以使用点语法为变量属性分配新值:

someVideoMode.resolution.width = 1280
print("The width of someVideoMode is now \(someVideoMode.resolution.width)")
// Prints "The width of someVideoMode is now 1280"

//4.结构类型的成员初始化器
//所有结构都有一个聪明的、自动生成的初始化器,您可以使用它来初始化新结构实例的成员属性。新实例属性的初始值可以按名称传递给成员初始化器:

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

//与结构不同,类实例不接收默认的成员初始化器

//二、结构和枚举是值类型
//值类型是一个类型,当它被分配给一个变量或常量,或者把它传递给一个函数作为参数时,它的值是被复制过去的。
//在前面的章节中,您实际上已经广泛使用了值类型。
//事实上,Swift中的所有基本类型——整数、浮点数、布尔值、字符串、数组和字典都是值类型,它们是以结构的方式被实现。
//Swift中所有结构和枚举都是值类型。这意味着你创建的任何结构和枚举实例,以及它们作为属性的任何值类型,在你的代码中传递时都会被复制。

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

//下面这个例子,它使用了上一个例子中的Resolution结构:

let hd = Resolution(width: 1920, height: 1080)
var cinema = hd

//此示例声明了一个名为hd的常量,并将其设置为Resolution实例,初始化为使用全高清视频的宽度和高度(1920 像素宽 x 1080 像素高)
//然后它声明一个变量cinema,并将其设置为hd的当前值。
//因为Resolution是一个结构,当把它分配给cinema的时候,根据现有实例的复制了一份副本并分配给cinema。
//虽然hd和cinema现在有相同的宽度和高度,但是它们是两种完全不同的实例

//接下来,将cinema的width属性修改为用于数字电影放映的稍宽的2K标准的宽(2048 像素宽,1080 像素高):

cinema.width = 2048

//检查cinema的width属性显示它确实已更改为2048:

print("cinema is now \(cinema.width) pixels wide")
// Prints "cinema is now 2048 pixels wide"

//但是,原始hd实例的width属性仍然是旧值1920:

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

//当cinema被赋予hd的当前值时,存储在hd的值被复制到新cinema实例中。
//最终结果是两个完全独立的实例包含相同数值的。但是,由于它们是独立的实例,因此设置cinema的值为2048的宽度,不会影响hd中存储的宽度

//枚举中的情况同样是这样:

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"

//当rememberedDirection被分配为currentDirection的值时,它实际上复制了一份该值的副本。
//当更改currentDirection的值后,不会影响存储在rememberedDirection的值

//三、类是引用类型
//不同于值类型,当引用类型分配给常量或变量,或者传递给函数的是,它不会复制一份副本,而使用同一个已经存在的实例的引用

//这是一个示例,使用上面定义的类VideoMode:

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

//接下来,tenEighty分配给一个alsoTenEighty常量,alsoTenEighty修改的帧速率:

let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0

//由于类是引用类型,tenEighty和alsoTenEighty实际上都指向同一个VideoMode实例。实际上,它们只是同一个实例的两个不同名称
//检查tenEighty的frameRate属性表明它正确展示为VideoMode实例的新帧速率30.0:

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

//请注意,tenEighty和alsoTenEighty被声明为常量,而不是变量。但是,仍然可以更改tenEighty.frameRate和alsoTenEighty.frameRate的值
//因为tenEighty和alsoTenEighty作为常量本身的值实际上并没有改变。
//tenEighty和alsoTenEighty他们自己不“存储”VideoMode实例——相反,他们都引用VideoMode的实例。
//改变frameRate是改变VideoMode的属性,而不是改变VideoMode的常量引用的值。

//1.身份运算符
//因为类是引用类型,所以多个常量和变量可能在幕后引用同一个类的单个实例。
//注意:结构和枚举并非如此,因为它们在分配给常量或变量或传递给函数时总是会被复制。
//有时,找出两个常量或变量是否指向一个类的同一个实例会很有用。为了实现这一点,Swift提供了两个身份运算符:

//等同于(===)
//不等同于(!==)

if tenEighty === alsoTenEighty {
    print("tenEighty and alsoTenEighty refer to the same VideoMode instance.")
}
// Prints "tenEighty and alsoTenEighty refer to the same VideoMode instance."

//请注意,相同于(由三个等号或===表示)并不意味着与等于(由两个等号或==表示相同。
//相同于意味着两个常量或变量类型引用的类实例完全相同。等于意味着两个实例在值上被视为相等或等效。

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

推荐阅读更多精彩内容

  • 本页包含内容: 类和结构体对比结构体和枚举是值类型类是引用类型类和结构体的选择字符串、数组、和字典类型的赋值与复制...
    雨影阅读 253评论 0 0
  • 前言类和结构体是人们构建代码所用的一种通用且灵活的构造体。我们可以使用完全相同的语法规则来为类和结构体定义属性(常...
    Mr_yinwei阅读 762评论 0 1
  • 翻译能力有限,如有不对的地方,还请见谅!希望对Swift的学习者有所帮助,使用的编写工具:JQNote InNot...
    JackYan0927阅读 378评论 0 0
  • 1. 枚举 枚举为一组相关的值定义了一个共同的类型,使你可以在你的代码中以类型安全的方式来使用这些值。 在 Swi...
    路飞_Luck阅读 344评论 0 0
  • 类和结构 类和结构是通用的,灵活的构造,它们成为程序代码的构建块。您可以使用与常量,变量和函数完全相同的语法来定义...
    Fuuqiu阅读 169评论 0 0