Swift基础入门知识学习(12)-枚举(列举)-讲给你懂
懂
类(class)及结构体(structure),可以让你将多个相关的函数及值储存在内,以及更多的特性。目前你可以稍微把类与结构体看为进阶豪华版的函数。
类与结构体的比较
与结构体相比,类还有以下的其他功能:
定义一个类及结构体分别要使用class及struct关键字,并接着一组大括号{ },格式如下:
- 类或结构体内的变数或常数,会称作属性(property)。而类或结构体内的函数,会称作方法(method)。
- 每次定义一个新的类或结构体时,实际上你是定义了一个新的 Swift 类型,所以在习惯上会以大驼峰式命名法来为类与结构体命名,以符合标准 Swift 类型的大写命名风格(像是String、Int)。相对地,使用小驼峰式命名法为属性与方法命名(与常数、变数及函数相同),以便与类区分。
以下是定义结构体与类的例子:
struct CharacterStats {
var hp = 0.0
var mp = 0.0
}
class GameOne {
var stats = CharacterStats()
var attackSpeed = 1.0
var name: String?
}
上述程式中,定义了一个名为CharacterStats的结构体来描述一个游戏角色的状态,这个结构体包含了两个属性(属性即为储存在类或结构体内的常数或变数):hp跟mp,分别表示角色血量与法力的最大值。当这两个属性被初始化为0.0时,会被自动推断为Double类型。
接着定义了一个名为GameOne的类,描述一个游戏角色的基本资讯,这个类包含了三个属性,第一个为角色的状态,会被初始化为一个CharacterStats结构体的实例,其后两个属性为攻速及名字,攻速有预设值1.0,名字则为一个可选类型String?,会被自动指派为一个预设值nil,表示一开始没有name值。
类与结构体五个重要区别
- 类不附带合成的成员初始化器。
- 一个类可以构建在另一个类上(“继承”),获得属性和方法。
- 结构体的副本始终是唯一的,而类的副本实际上指向相同的共享数据。
- 类有取消初始化器,这些方法是在类实例被销毁时调用的方法,但结构体没有。
- 常量类中的变量属性可以自由修改,但常量结构中的变量属性不能修改。
类与结构体实例
定义类与结构体,就像是给了一个固定的规格,譬如说明一个游戏角色会有血量、法力、攻速、名字这些资讯,但使用上,必须依照这个规格(即类或结构体)来实际建立一个角色,这个动作就是生成类或结构体的实例(instance)。
实例有些地方会翻译成实体,同样都是指instance。
类与结构体都使用建构器语法来生成实体,建构器最简单的形式就是在类或结构体名称后面加上一个小括号()语法,这种方式建立的实例,其内的属性都会被初始化为预设值,如下:
let someStats = CharacterStats()
let someGameCharacter = GameOne()
上述程式中,someStats就是一个CharacterStats结构体的实例,someGameCharacter则为一个GameOne类的实例。
可以看到生成实例的方式与呼叫函数相似,所以习惯上两种命名方式会不一样,一个使用大驼峰式命名法,另一个使用小驼峰式命名法,来作区别。
取得属性
使用点语法(dot syntax)可以取得实例的属性(property)。规则为实例名称后加上一个点号.,然后紧接着属性名称,如下:
// 这边使用前面定义的 CharacterStats 结构体 及生成的实例 someStats
// 因为没有初始值 所以会使用预设值 这边会印出:someStats 血量最大值为0.0
print("someStats 血量最大值为(someStats.hp)")
你可以连结多个点语法,直接取得子属性,像是someGameCharacter中stats属性的hp属性,如下:
// 这边使用前面定义的 GameOne 类
// 及其生成的实例 someGameCharacter
// 印出:血量最大值为0.0
print("血量最大值为(someGameCharacter.stats.hp)")
也可以将新的值指派给实例的属性,如下:
// 将 someGameCharacter 的血量最大值指派为 500
someGameCharacter.stats.hp = 500
// 再次印出 即会变成:500.0
print(someGameCharacter.stats.hp)
结构体类型的成员逐一建构器
所有结构体都有一个自动生成的成员逐一建构器(memberwise initializer),当要生成一个结构体的实例时,用来初始化实例内的属性,如下:
// 这边使用前面定义的 CharacterStats 结构体 生成新的实例 someoneStats
let someoneStats = CharacterStats(hp: 120, mp: 100)
// 印出:120.0
print(someoneStats.hp)
结构体和列举是值类型
值类型(value type)在被指派给一个变数、常数或被传递给一个函数时,实际上操作的是其拷贝(copy)。指派或传递后,两者的值即各自独立,不会互相影响。
在前面章节中,其实已经大量使用了值类型。实际上,在 Swift 中,所有的基本类型:整数、浮点数、布林值、字串、阵列和字典,都是值类型,并且背后都是以结构体的形式实作。
结构体和列举也都是值类型,代表它们的实例及其内任何值类型的属性,在被指派或传递时都会被复制。例子如下:
// 这边使用前面定义的 CharacterStats 结构体
var oneStats = CharacterStats(hp: 120, mp: 100)
var anotherStats = oneStats
// 这时修改 anotherStats 的 hp 属性
anotherStats.hp = 300
// 可以看出来已经改变了 印出:300.0
print(anotherStats.hp)
// 但 oneStats 的属性不会改变
// 仍然是被生成实例时的初始值 印出:120.0
print(oneStats.hp)
在oneStats被指派给anotherStats时,其实是将oneStats内的值进行拷贝(copy),接着将拷贝的资料储存给新的实例anotherStats,两者是完全独立的实例,彼此不会互相影响。
类是参考类型
与值类型不同,参考类型(reference type)在被指派给一个变数、常数或被传递给一个函数时,操作的不是其拷贝,而是已存在的实例本身。例子如下:
// 这边使用前面定义的 GameOne 类
let archer = GameOne()
archer.attackSpeed = 1.5
archer.name = "弓箭手"
// 指派给一个新的常数
let superArcher = archer
// 并修改这个新实例的属性 attackSpeed
superArcher.attackSpeed = 1.8
// 可以看到这边印出的都为:1.8
print("archer 的攻速为 (archer.attackSpeed)")
print("superArcher 的攻速为 (superArcher.attackSpeed)")
从上述程式可以知道,archer跟superArcher实际上是对同一个实例做操作。也就是同一个实例的两个不同名称。
有一点要注意的是,可以看到archer跟superArcher都被宣告为常数(使用let宣告),但依然可以改变其内的属性archer.attackSpeed跟superArcher.attackSpeed,因为这两个常数储存的是一个GameOne类实例的参考(参考其在记忆体空间内配置的位置),而不是储存这个实例,所以这个实例的attackSpeed属性可以被修改,但不会修改到常数的值。
恒等运算子
因为类是参考类型,可能有多个常数和变数在后台同时参考某一个类实例,所以 Swift 提供了两个恒等运算子,能够判断两个变数或常数是不是参考同一个类实例:
等价于 ===
不等价于 !==
以下是一个例子:
// 使用前面宣告的两个常数 archer 与 superArcher
if archer === superArcher {
print("没错!!!是同一个类实例")
}
请注意=与的不同
使用类或结构体?
类与结构体有很多相似的地方,要如何决定每个资料建构要定义为类还是结构体,可以参考以下原则:
如果符合上述一条或以上原则,则建议定义为结构体,其余则是定义为类。
所以实际上,大部分的自定义资料建构都应该使用类。
当符合一条或多条以下条件时,请考虑构建结构体:
- 结构体的主要目的是用来封装少量相关简单数据值。
- 有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用。
- 任何在结构体中储存的值类型属性,也将会被拷贝,而不是被引用。
- 结构体不需要去继承另一个已存在类型的属性或者行为。
举例来说,以下情况中适合使用结构体:
- 几何形状的大小,封装一个width属性和height属性,两者均为Double类型。
- 一定范围内的路径,封装一个start属性和length属性,两者均为Int类型。
- 三维坐标系内一点,封装x,y和z属性,三者均为Double类型。
原文地址:https://blog.csdn.net/weixin_42385177/article/details/121710437
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_36770.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!