为什么写这篇文章
Swift其实很早就开始接触了,也一直在使用Swift开发项目。回过头来看看,有一个很明显的例子就是代码用的最多的还是类,觉得还是有必要再回过头来看看这哥三(协议,下一篇文章讲解)。
本文章参考:https://www.jianshu.com/p/78a6a4941516,结合自己项目的代码完成。
枚举enum
和C、Objective-C中枚举的不同,Swift 中的枚举成员在被创建时不会分配一个默认的整数值。而且不需要给枚举中的每一个成员都提供值(如果你需要也是可以的)。
enum CardEidtType {
case name //名称
case cmp //公司
case title //职称
}
枚举中有两个值概念:原始值(raw value)、关联值(associated value)。
- 原始值
enum CardEidtType: Int {
case name = 1 //名称
case cmp = 2 //公司
case title = 3 //职称
}
这种用法类似OC里面的枚举
- 关联值
enum PassportProvider {
case checkPhoneIsExisted(phone: String)
case userRegister(role: Int)
}
这种用法只是给成员提供类型,没有指定具体值,用法:
switch self {
case .checkPhoneIsExisted(let phone):
params["mobile"] = phone
break
default:
break
}
结构体struct
- 定义结构体类型时其成员可以没有初始值,类必须要有
- 初始化赋值在括号里面传参, 如果成员均有默认值,可以都不传。但是只能都传或者都不传,如果要像class一样可以动态缺省,就需要自定义了初始化器。
public struct SearchSortType{
public var name: String
public var sortBy: String
// init() {name: String, sortBy: String} 自定义了初始化器
public static func getList() ->[SearchSortType]{
return[
SearchSortType(name: "默认", sortBy: "5"),
SearchSortType(name: "服务费率最高", sortBy: "1"),
/***/
]
}
public mutating func modifyName(name: String){
self.name = name
}
}
- 修改结构体里面成员的方法需要添加
mutating
关键字
由于结构体是值类型,Swift规定不能直接在结构体的方法(初始化器除外)中修改成员。原因很简单,结构体作为值的一种表现类型怎么能提供改变自己值的方法呢,但是使用mutating我们便可以办到这点,当然这也是和类的不同点。
- 下面代码s1和s2打印出来,微微一笑,好像明白了什么。
var s1 = SearchSortType(name: "", sortBy: "0")
var s2 = s1
s2.name = "最高"
print("\(s1)") // SearchSortType(name: "", sortBy: "0")
print("\(s2)") // SearchSortType(name: "最高", sortBy: "0")
总结
能使用struct就不要使用class:
- 使用struct不需要考虑内存泄漏和多线程读写的问题,因为在传递值的时候它会进行值的copy。
- struct存储在栈中,class存储在堆中,struct更快
共性
都能提供封装,能有初始化方法,能有计算属性,能采用协议
不同点
- class是引用类型;struct是值类型
- class支持继承;struct不支持继承
- class支持引用计数;struct不支持
- class支持类型转换;struct不支持(这里和2点是相关的)
- class支持析构;struct不支持
- class没有提供默认的初始化方法;struct提供默认的初始化方法
- class声明的方法修改属性不需要mutating关键字;struct需要