1.枚举
枚举为一组相关的值定义了一个
共同的类型
,使你可以在你的代码中以类型安全
的方式来使用这些值。 枚举成员可以指定任意类型
的关联值存储到枚举成员中,就像其他语言中的联合体(unions)
和变体(variants)
。你可以在一个枚举中定义一组相关的枚举
成员,每一个枚举成员都可以有适当类型的关联值
。
枚举支持Int
、Double
、String
等基础类型,也有默认枚举值
(String
类型默认枚举值为case
的key
名称,Int
、Double
数值型默认枚举值为0
开始,+1
递增。
// 写法一
// 不需要逗号隔开
enum Weak1 {
case MON
case TUE
case WED
case THU
case FRI
case SAT
case SUN
}
// 写法二
// 也可以直接一个case,然后使用逗号隔开
enum Weak2 {
case MON, TUE, WED, THU, FRI, SAT, SUN
}
// 定义一个枚举变量
var w: Weak1 = .MON
/*
String类型的enum
- =左边的值是枚举值,例如 MON
- =右边的值在swift中称为 RawValue(原始值),例如 "MON"
- 两者的关系为:case 枚举值 = rawValue原始值
*/
enum Week: String{
case MON = "MON"
case TUE = "TUE"
case WED = "WED"
case THU = "THU"
case FRI = "FRI"
case SAT = "SAT"
case SUN = "SUN"
}
2.结构体
声明结构体的关键字是struct,使用起来和类相似,但类的成员是引用类型,而结构体的成员是值类型。
值类型在传递和赋值的时候,是进行复制的,那也就是说在修改一处复制体的时候,原来被复制的对象是不受影响的。
引用类型在传递和赋值的时候,是传递引用对象的一个“指向”,所以当对该引用进行修改的时候,是直接直接修改到最原始的对象,即,一旦修改值,则对该原始对象的所有引用都会被同步修改。
在内存中,引用类型的变量是在堆上存储和操作的。值类型的变量是在栈上存储和操作的。两者相比起来,在堆上的变量操作会比较复杂和耗时。所以苹果官方推荐使用结构体,这样可以提高App的运行效率。
结构体的优势:
结构较小,适用于复制,相比一个class的实例被多次引用,struct结构体更加安全。
无须担心内存泄漏或者多线程冲突安全。
struct student {
var name = "name"
var index = 202100
var height = 160.00
var profession = "profession"
var sex = "男"
}
var xiaoMing = student()
xiaoMing.name = "xiaoMing"
xiaoMing.index = 202101
xiaoMing.height = 172.5
xiaoMing.profession = "计算机科学与技术"
xiaoMing.sex = "男"
print("\(xiaoMing)")
运行结果:
student(name: "xiaoMing", index: 202101, height: 172.5, profession: "计算机科学与技术", sex: "男")
3.类
类是引用类型。也就意味着一个类类型的变量并不直接存储具体的实例对象,是对当前存储具体 实例内存地址的引用。
// 定义一个类
class PhoneClass {
// 定义价格属性
var price: Int = 0
// 定义品牌属性
var brand: String = ""
// 定义型号属性
var model: String = ""
// 定义降价促销方法
func discount() {
price -= 800
}
// 当三个属性都有默认值的时候,可以不写 init
init(price: Int, brand: String, model: String) {
self.price = price
self.brand = brand
self.model = model
}
}
// 创建 class 实例
var huaweiPhone = PhoneClass(price: 5999, brand: "huawei", model: "p40 pro")
// 类属于引用类型,变量传递后,修改值会影响引用的变量
let huaweiNewPhone = huaweiPhone
huaweiPhone.price += 1000
// 值修改后会影响原变量的值,huaweiPhone.price: 6999, huaweiNewPhone.price: 6999
print("huaweiPhone.price: \(huaweiPhone.price), huaweiNewPhone.price: \(huaweiNewPhone.price)")
4.属性
存储属性就是存储在特定类或结构体实例里的一个常量或变量。存储属性可以是变量存储属性(用关键字 var 定义),也可以是常量存储属性(用关键字 let 定义)。
// Swift5 存储属性
class Phone {
var system = "iOS"
// 常量存储属性,一旦实例化,不能修改
let brand: String
// 存储属性,可以修改
var price: Int
// 当类被实例化时,要保证所有的属性都初始化完成,除非属性有默认值
init(brand: String, price: Int) {
self.brand = brand
self.price = price
print("brand: (brand), price: (price)")
}
}
// 修改类的属性值
let iPhone = Phone(brand: "iPhone", price: 5999)
iPhone.price -= 600
// 延时存储属性:当类初始化时,延时存储属性不被初始化,当被调用时才初始化
class Consumer {
var money: Int
lazy var phone: Phone = Phone(brand: "iPhone", price: 6999)
init(money: Int) {
self.money = money
}
}
// 只初始化了money
var richMan = Consumer(money: 100_000)
// 延时属性 phone 被初始化
print(richMan.phone) // brand: iPhone, price: 6999
-
计算属性
特征:仅有get(readOnly语义)或有get+set的属性是计算型属性,有get+set的属性仅作为其他属性的外部接口
计算型属性本身不占用内存内控,所以不能赋值
get+set为计算型属性的原因:
真正赋值的过程是存在于set方法中并被底层包装掉的,如果我们手动实现了set方法,就无法进行正确的赋值
get+set正确的使用方法:作为其他属性的外部接口
// Swift5 计算属性
class Android {
// 常量存储属性,一旦实例化,不能修改
let system: String = "android"
// 存储属性
var version = "12"
// api 级别
var apiLevel: String = "31"
// 计算属性,向外提供接口访问类实例的某种状态,这种状态和类实例的属性值相关联
var info: String {
get {
return "system: (system), version: (version), level: (apiLevel)"
}
set {
// 默认使用 newValue 指代新值
version = newValue.split(separator: "-").first?.description ?? ""
apiLevel = newValue.split(separator: "-").last?.description ?? ""
}
}
// 计算属性 价格,简单模拟
var price: ClosedRange<Int> {
get {
// 当版本高于30时,价格在[4000,6999]之间
if (apiLevel > "30") {
return 4000...6999
} else {
return 1000...3999
}
}
// 自定义传值名称 newPrice
set(newPrice) {
// 当价格高于3999时,版本为31
if (newPrice.lowerBound > 3999) {
apiLevel = "31"
version = "12"
} else {
apiLevel = "30"
version = "11"
}
}
}
}
var newPhone = Android()
print(newPhone.info) // system: android, version: 12, level: 31
newPhone.info = "11-30"
print(newPhone.info) // system: android, version: 11, level: 30
newPhone.price = 4000...4999
print(newPhone.info) // system: android, version: 12, level: 31