学习swift从青铜到王者之swift结构体和类08
定义
// 定义类 class StudentC{
}
// 定义结构体 struct StudentS{
}
定义存储属性
// 定义类 class StudentC{ var name:String = "yhx" } // 定义结构体 struct StudentS{ var name:String }
注意:在类中定义属性必须要注意,如果你定义的存储属性不是可选值类型,必须进行初始化,不然编译会报错,但是结构体不会报错,因为系统默认会给结构体创建初始化方法
定义函数
// 定义类 class StudentC{ static var des:String = "学生的类" var name:String! func getName()->String{ return name } class func describe()->String{ return des } static func getClassDescribe()->String{ return des } } // 定义结构体 struct StudentS{ static var des:String = "学生的结构体" var name:String static func describe()->String{ return "这是一个定义学生的类" } } //类可以使用关键字static class 修饰方法,但是结构体只能使用关键字static修饰
扩展下标
class StudentC{ var names:[String] = ["1","2","3","4","5"] subscript (index:Int)->String?{ get{ if names.count <= index{ return nil } return names[index] } } } // 定义结构体 struct StudentS{ var names:[String] = ["1","2","3","4","5"] subscript (index:Int)->String?{ get{ if names.count <= index{ return nil } return names[index] } } } // 执行 let student1 = StudentC() print(student1[3])
初始化
// 定义类 class StudentC{ var name:String init( name:String) { self.name = name } } // 定义结构体 struct StudentS{ var name:String init(name:String) { self.name = name } } let student1 = StudentC(name: "yhx1") let student2 = StudentS(name: "yhx2")
结构体默认会有初始化方法
struct StudentS{ var name:String } let student2 = StudentS(name: "yhx")
扩展功能
extension StudentC{ func describe()->String{ return "学生" + self.name } } extension StudentS{ func describe()->String{ return "学生" + self.name } }
实现协议
// 定义一个协议 protocol Capacity{ func draw() // 协议方法 } // 定义类 class StudentC:Capacity{ // 实现协议方法 internal func draw() { } var name:String init( name:String) { self.name = name } } // 定义结构体 struct StudentS:Capacity{ // 实现协议方法 internal func draw() { } var name:String }
继承
// 定义基类 class Person{ var name:String init( name:String) { self.name = name } } // 定义类 class StudentC:Person{ var score:Float init( name:String,score:Float) { self.score = score super.init(name: name) self.name = name } } 提示:结构体不能继承结构体
mutating 关键字的作用
/*结构体和枚举都是值类型,但是默认值类型的对象方法不能修改属性值,但是要修改怎么办呢?就必须在函数前面加mutating*/ //例子1 protocol Action{ var myY:Int{ mutating get} } struct Point{ var x:Int var y:Int // 结构体或者枚举修改值必须在函数前面加mutating mutating func modifyX(x:Int){ self.x = x } // 注意计算属性,mutating 要加载getter方法前面 var myY:Int{ mutating get { self.y = self.y*2 return y } } } // 例子2 struct Point { var x = 0.0, y = 0.0 mutating func moveBy(x deltaX: Double, y deltaY: Double) { self = Point(x: x + deltaX, y: y + deltaY) } } // 例子3 enum TriStateSwitch { case off, low, high mutating func next() { switch self { case .off: self = .low case .low: self = .high case .high: self = .off } } } /*提示: 1.计算属性setter方法不用修改属性值不用添加mutating 2.计算属性setter方法中修改属性值的时候,一定要加mutating */
检测两个对象地址是不是相同
class StudentC{ var name:String init( name:String) { self.name = name } } let student1 = StudentC(name: "yhx") let student2 = student1 if student1 === student2{ print("地址相同") } //运行结果:地址相同
注意:类是引用类型,结构体是值类型,不能使用===/!== 判断地址
Deinitializers使一个类的实例来释放任何资源分配
// 定义类 class StudentC{ var name:String init( name:String) { self.name = name } deinit { // 释放资源 } } //提示:结构体没有deinit 方法
高级话题
1.创建相同属性的结构体比类更加节省内存
2. 什么时候用结构体
1.该结构的主要目的是封装几个相对简单的数据值
2.如果你希望你的结构在传递的时候被赋值而不是引用
3.希望结构在传递的时候,内部的属性也被复制而不是引用
4.不需要继承属性或者方法
主要应用场景(只包含非对象类型)
1.定义Size
2.定义范围Range
3.定义坐标XYZ
...