Swift -- 7.3 类和结构体
swift的类和结构体高度相似,无论是定义语法还是用法上,swift的类和结构体都具有高度的相似性
区别是:结构体不支持继承(自然也不支持类型转换了。。。。。这个,还不太理解)
结构体不支持定义析构器
结构体是值类型,而类是引用类型
苹果的官方文档中说结构体的使用场景不多,主要还是应该使用类
那么哪些场景需要用到结构体呢:
苹果的官方文档表示,当满足以下一个或多个条件时,应该使用结构体
*结构体的主要目的是用于封装少量相关的简单数据值
如果程序需要让该实例在赋值或参数传递时会自动复制副本,则应该使用结构体
如果程序明确该类型无须继承另一个已有的的类或被其他类继承,则可以考虑使用结构体
一个类中包含三种成员:构造器,属性,方法
swift语言通过类名后添加圆括号来表示调用构造器,从而返回该类的实例
如果程序员自己没有写构造器,系统会提供一个默认的无参的构造器,如果自己写了,系统就不提供默认的构造器
class修饰的成员(类成员)不能访问没有class修饰的成员(实例成员)
定义结构体和定义类的主要区别是:结构体不支持继承,因此结构体不能使用final修饰
如果程序员没有为结构体提供构造器,系统则会为该结构体提供两个构造器:一个无参的构造器,一个初始化所有存储属性的构造器
class,static两个修饰符的作用几乎完全相同,只是使用场景不同。定义类时,使用class修饰类中成员,将遮羞成员转成类型相关的成员,没有该修饰符的是实例成员;定义结构体或枚举时,使用static修饰枚举或结构体的成员,将这些成员转成类型相关的成员,没有该修饰符修饰的是实例成员,所以static和class两个修饰符不会同时出现
swift语言要求类中定义的存储属性必须指定初始值,要么在定义时指定初始值,要么在构造器中指定初始值
swift的构造器隐式的将self作为返回值
定义和创建实例
//定义一个person类 class Person {var name : String = ""var age : Int = 0func say(content:String){print(content)} }//定义一个dog结构体 struct Dog {var name : Stringvar age : Intfunc run(){print("\(name) is running")} }//创建实例 var p6:Person p6 = Person() var p5 = Person() var p7 = p6 p6.name = "sun" p6.say("swift is so easy") print(p6.name) print(p5.name) p6.name = "zhu" print(p7.name)var dogfff = Dog(name: "doggy", age: 4) print(dogfff.age) dogfff.run() var dogggg = dogfff dogggg.name = "happy" print(dogfff.name)
使用===和!==来判断引用类型是否指向同一个实例
class User {var name:Stringvar age:Intinit(name:String , age:Int){self.name = nameself.age = age} } var u1 = User(name: "abe", age: 12) var u2 = User(name: "abe", age: 12) print(u1 === u2) var u3 = u1 print(u3 === u1)struct Level {var grade:Int }var v1 = Level(grade: 1) var v2 = Level(grade: 2) //print(v1 === v2) 这里不能这样写,因为只有引用类型能这样比较
运算符重载
func == (left:User, right:User) -> Bool {return left.name == right.name && left.age == right.age }func != (left:User, right:User) -> Bool {return !(left == right) } var resultttt = u1==u2 print(resultttt)
存储属性
枚举不能定义实例存储属性,只有类和结构体才能定义实例存储属性;枚举,类,结构体都可以定义类型存储属性
在结构体中,声明的存储属性可以不赋予初始值,因为系统会自动生成一个构造器,用来赋予初始值
struct FixedLengthRange {var start: Intlet length: Int } var rg = FixedLengthRange(start: 2, length: 10) rg.start = 5
延迟存储属性
在第一次被调用时才会被计算初始值的属性,声明延迟存储属性需要使用lazy修饰符
延迟存储是一种延迟加载(lazy load)机制,当某个实例持有另一个创建成本较大的实例的引用时,使用延迟存储可以降低内存开销,从而提升程序性能
class Dept {var id : Intvar info : Stringinit(id : Int){self.id = idNSThread.sleepForTimeInterval(2)self.info = "2 second late"} } class User4 {var id:Int = 0lazy var dept = Dept(id: 20)//dept 属性会在被调用的时候才被初始化,提升了程序的性能var nicks = [String]() } var usersss = User4() usersss.nicks.append("sun") usersss.nicks.append("qiqiqi") print(usersss.nicks)
计算属性
枚举,结构体,类都可以定义计算属性
enum Seasonnn {case Spring, Summer, Fall, Wintervar info:String{get{print("the get method is running")switch(self){case .Spring:return "flower"default:return "no"}}set (newValue){print("the set method is running and the pragmatic is \(newValue)")}} } var s = Seasonnn.Spring print(s.info) s.info = "baby"//简化的set方法 enum Seasonnn2 {case Spring, Summer, Fall, Wintervar info:String{get{print("the get method is running")switch(self){case .Spring:return "flower"default:return "no"}}set{print("the set method is running and the pragmatic is \(newValue)")}} }/* 声明只读的计算属性 没有set方法,只有get方法 这里可以省略get这个关键字和花括号 */ enum Seasonnn3 {case Spring, Summer, Fall, Wintervar info:String{get{print("the get method is running")switch(self){case .Spring:return "flower"default:return "no"}}} } var ss = Seasonnn3.Spring
属性观察者机制
为了让程序能在属性被赋值时获得执行代码的机会,swift提供了属性观察者机制,属性观察者其实就是两个特殊的回调方法
willSet(newValue) 被观察的属性即将被赋值之前自动调用该方法
didSet(oldValue) 被观察的属性被赋值完成之后自动调用该方法
willSet部分可以显式指定
class People {var name:String = "" {willSet{if(newValue.characters.count > 6) || (newValue.characters.count < 2){print("the name you input is iligo")}else{print("set name success")}}didSet{print("set name over")}} } var jane = People() jane.name = "d" print(jane.name)//虽然这两个方法有监察作用,但是并不能阻止赋值的执行
转载于:https://www.cnblogs.com/chebaodaren/p/5590994.html
Swift -- 7.3 类和结构体相关推荐
- Swift中的类和结构体(2)
Swift中的类和结构体(2) 异变方法 方法调度 影响函数派发方式 异变方法 在Swift中,值类型属性不能被自身的实例方法修改,编译器不会通过编译,报错Left side of mutating ...
- Swift 中的类和结构体
Swift 中的结构体的能力被大大加强,不仅可以拥有属性,还以有方法.构造函数.甚至是扩展和遵守协议.这样的结构体和类有很多相同点: 属性:存储数据 方法:提供一些功能 下标:可以使用下标语法 构造器 ...
- swift 学习- 10 -- 类和结构体
// '类和结构体' 是人们构建代码所使用的一种通用且灵活的构造体, 我们可以使用完全相同的语法规则来为 '类和结构体' 定义属性 (变量 和 常量) 和添加方法, 从而扩展 类和结构体 的功能 // ...
- [Swift]枚举、类与结构体的对比
为什么80%的码农都做不了架构师?>>> ###枚举.类与结构体的对比### ####枚举与其他两者的关系#### 首先说枚举,相对比较好区分,因为我们知道,枚举与其他两者最大 ...
- ios 结构体跟枚举变量的区别_[Swift]枚举、类与结构体的对比
###枚举.类与结构体的对比### ####枚举与其他两者的关系#### 首先说枚举,相对比较好区分,因为我们知道,枚举与其他两者最大的相同之处就在于都可以定义方法. 而其他的更多特性,对于枚举基本没 ...
- Object-C---gt;Swift之(八)类和结构体
在Swift中类和结构体有高度的相似性.二者主要区别是: 1. 结构体不支持继承 2. 结构体不支持定义析构器 3. 结构体是值类型,而类是引用类型 定义类语法格式: [修饰符]class 类名 { ...
- Swift面向对象基础(上)——Swift中的类和结构体(下)
2019独角兽企业重金招聘Python工程师标准>>> 学习来自<极客学院> 1 import Foundation 2 3 class User { 4 var nam ...
- Swift 中的类与结构体
- Swift之深入解析类和结构体的本质
一.类和结构体的异同 Swift中,类和结构体有许多相似之处,但也有不同.内存分配可以分为堆区(Heap)和栈区(Stack),由于栈区内存是连续的,内存的分配和销毁是通过入栈和出栈操作进行的,速度要 ...
最新文章
- Android常用逆向工具总结(未完待续)
- 设计模式-生产者消费者模式
- android_launcher的源码详细分析和壁纸修改 .
- OpenCV学习笔记(三十六)——Kalman滤波做运动目标跟踪 OpenCV学习笔记(三十七)——实用函数、系统函数、宏core OpenCV学习笔记(三十八)——显示当前FPS OpenC
- linux命令之查看进程运行动态库依赖及打开文件-lsof
- 并查集的一般操作 ③
- 20160626001 O2O Website
- db2 之 入门实验
- 易语言写c盘配置文件,易语言写配置文件的方法
- yml连接sqlserver_springboot配置双数据源 MySQL和SqlServer
- wmic cpu get processorid获取的都一样_DJL 之 Java 玩转多维数组,就像 NumPy 一样
- c 宏变量/宏函数/log
- 数据:以太坊上稳定币流通量突破600亿美元,年内增幅达187%
- Linux工具篇 | Linux下安装repo工具
- windows如何根据句柄hwnd显示和隐藏窗口
- uint16 累加_在一个驱动程序中看到uint16,uint32,unit8,int8是什么意思?有何作用?...
- 视频教程-微信公众号二维码签到和抽奖软件-微信开发
- 郝斌c语言大纲百度云,C语言学习大纲 郝斌(讲解)
- nbextensions安装完不显示,404 GET /static/components/marked/lib/marked.js?v=20230331152041
- python基于django的考研报名交流平台
热门文章
- java 如何判定消息已在队列_【05期】消息队列中,如何保证消息的顺序性?
- PointConv论文阅读笔记
- TX1在opencv中调用gstreamer解码海康IP摄像头
- 扩展指令集--指令参考说明
- java version 和javac版本不一致_windows安裝多個版本的jdk,解決java-version和javac-version版本不一致的問題...
- 贪心法——最优装载问题
- javascript进制转换_《算法笔记》3.5小节——入门模拟-gt;进制转换
- php如何按日期统计,关于按日获取统计信息:按日期获取统计信息 – 日期时间列 – mysql / php...
- java list装3组数据_数组转List的3种方法和使用对比!
- mysql truncate partition_实战mysql分区(PARTITION)