在OC概念中经常提到的是类,但是在swift底层声明中已经大部分使用了struct结构体,下面我们就来讲解一下swift中的结构体.
一、类与结构体的区别
- 语义
- 类: 引用类型(引用语义),需要自己管理引用计数,引用值的变化
- 结构体:可以被直接持有及访问,不会被引用,但是会被复制.也就是说,结构体的持有者是唯一的
拓展:
byte,short,int,long,float,double,decimal,char,bool 和 struct 统称为值类型。
string,类等皆为引用类型。
值类型变量声明后,不管是否已经赋值,编译器为其分配内存。此时该值存储于栈上;int i=10;执行之前为默认一个值0。
引用类型定义时在栈上开辟一个空间用来存放其在堆上的地址,当赋值或者实例化时候就会在堆上开辟一个空间,然后把堆中的地址存放在栈中,这时候栈就存放了其地址。
2. 内存管理方式
- 类: 类的实例只能通过引用来间接地访问,类能有很多个持有者
- 结构体: 可以被直接持有及访问,不会被引用,但是被复制,也就是说,结构体的持有者是唯一的
3. 共享代码
- 类: 通过继承来共享代码
- 结构体(以及枚举): 不能被继承,想要在不同的结构体或者枚举之间共享代码,我们需要使用不同的技术,比如像是组合、泛型以及协议拓展
二、结构体
结构体为值类型
值类型意味着一个值变量被复制时,这个值本身也会被复制,而不只限于对这个值的引用的复制.
let a = 12 let b = a a += 1 print (a) // 13 print (b) // 12 b的值没有根据a的值进行改变
而在swift中结构体的功能也被扩大化了,基本拥有了和类差不多的功能:
- 定义属性
- 定义方法
- 定义getter和setter
- 可以定义初始化器来设置初始状态
- 实现扩展的功能
- 遵循协议,并实现协议的方法
- 结构总是被复制,并且不使用引用计数
类具有结构不具备的附加功能:
- 继承允许一个类继承另一个类的特征
- 类型转换使你能够在运行时检查和解释类实例的类型
- 初始化器使一个类的实例能够释放它所分配的任何资源
- 引用计数允许多个引用到一个类实例
1.定义结构体和类,并且为其添加变量和方法
struct Resolution { var width = 0 var height = 0 func resolutionFun() { print("method of struct Resolution") } } class VideoMode { var resolution = Resolution() var interlaced = false var frameRate = 0.0 var name: String? func VideoMode() { print("method of class VideoMode") } }
2.类和结构体的初始化
let object Name = Class Name() let variable Name = Struct Name() let someResolution = Resolution() let someVideoMode = VideoMode()
访问属性
Swift中访问属性使用的是链式结构,访问属性的时候使用 .
print("The width of someResolution is \(someResolution.width)") print("The width of someVideoMode is \(someVideoMode.resolution.width)")
结构体的初始化
struct Resolution { var width = 0 var height = 0 } let resolution = Resolution(width:100,height:120) print("width:\(resolution.width),height:\(resolution.height)") 结果: width:100,height:120
首先要知道初始化器是系统本身的方法,我们只能去重写或者重载它
重载就是将父类已有的方法通过扩充参数的形式重新定义一遍。
class VideoMode { var _name: String init(){ _name = "Jin" } init(name:String){ _name = name; } } let videoModeNormal = VideoMode() print("name:\(videoModeNormal._name)") let videoModeCustom = VideoMode(name: "Jack") print("name:\(videoModeCustom._name)") 结果: name:Jin name:Jack
当然,struct的初始化方法也是可以这样实现的:
struct Resolution { var width: Double init(){ width = 100 } init(width:Double){ self.width = width; } } let resolutionNormal = Resolution() print("width:\(resolutionNormal.width)") let resolutionCustom = Resolution(width: 120) print("width:\(resolutionCustom.width)") 结果: width:100.0 width:120.0
类和结构体的选择
结构体实例通过值传递,类实例通过引用传递.这意味两者通过不同的任务,当你在考虑一个项目数据构造和功能的时候,你需要决定每个数据构造是定义成类还是结构体.
当符合一条或多条以下条件时,请考虑构建结构体:
- 结构体的主要目的是用来封装少量相关的简单数据值
- 有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用
- 任何在结构体中储存的值类型属性,也会被拷贝,而不是被引用
- 结构体不需要去继承另一个已存在类型的属性或者行为
为什么Swift中推荐使用Struct?
Swift 里更推荐使用值类型变量(struct)而不是引用类型(class)的变量,Swift中许多常见的数据类型,字符串,集合类型以及结构体和枚举都是值类型而非引用类型,值类型的变量在赋值时会自动进行一次低消耗的值拷贝,对比对象的copy要更加高效而且不存在线程安全的问题.
上面就是Swift中的Struct结构体.希望对大家有所帮助!!!