@H_404_4@注:本文为作者自己总结,过于基础的就不再赘述 ,都是亲自测试的结果。如有错误或者遗漏的地方,欢迎指正,一起学习。
1、枚举枚举是用来定义一组通用类型的一组相关值 ,关键字@H_404_4@enum,@H_404_4@case关键词表明新的一行成员值将被定义。
enum Direction{ case East case West case South case north}
这里定义了一个简单的枚举类型 , 里面有四个枚举元素 。
也可以用一行的形式
enum Direction{ case East,West,South,north}
可以这样来访问这个枚举类型@H_404_4@var dir = Direction.East ,这时候这个变量 @H_404_4@dir 已经被推断成@H_404_4@Direction ,重新赋值的时候 可以直接用短语法@H_404_4@dir = .West 。
相关值(Associated Values)你可以定义 Swift 的枚举存储任何类型的相关值,如果需要的话,每个成员的数据类型可以是各不相同的。
enum barcode { case UPCA(Int,Int,Int ) case QRCode(String)}
你可以这样给它赋值@H_404_4@var pro = barcode.UPCA(8,53627,29009,1) ,也可以这样修改@H_404_4@pro = .QRCode("DSLEKWLJELJAIWFLWKJF")
这样取值
switch pro{case .UPCA(let a1,let a2,let a3,let a4): print("\(a1),\(a2),\(a3),\(a4)")case .QRCode(let s): print(s)}
你也可以把let写在最前面
switch pro{case let .UPCA( a1,a2,a3,a4): print("\(a1),\(a4)")case let .QRCode(s): print(s)}
两个得到相同的结果 : @H_404_4@DSLEKWLJELJAIWFLWKJF
给枚举指定特定类型 (原始值)你可以给一个枚举指定类型 ,比如说String 类型 。
enum SignBuilding : String{ case Beijing = "天安门" case XiAn = "兵马俑"}
这里将 这个枚举定义成 字符串类型的 。
通过这样可以取到对应的值@H_404_4@print(SignBuilding.Beijing.rawValue)
也可以原始值隐式赋值
enum IntVal:Int { case Val1 = 1,Val2,Val3}
如果没给Val1赋值 ,默认是 0 。递增是 1 ,也可以 自己制定初始值 (这里我们给定了初始值1)
也可以使用原始值来初始化枚举 @H_404_4@let val = IntVal(rawValue: 2) @H_404_4@print(val) //Optional(IntVal.Val2),这里得到的结果是Optional类型 ,因为不是所有的数字都能匹配到对应的枚举类型 。如 :@H_404_4@let errorVal = IntVal(rawValue: 5) @H_404_4@print(errorVal) //nil
官方还给出了递归枚举 ,关键字 @H_404_4@indirect ,但是我这边尝试了好多次 ,这个关键字也没有变色 ,还会报错 。
enum Calculate{ case Num(Int) indirect case Plus(Calculate,Calculate) indirect case ChenFa(Calculate,Calculate)}
在网上搜了下 , 因为是2.0的新特性 ,网上也没有太多的解释。大家可以研究下 ,我也研究下 ,研究出来再来补上。
枚举里面还可以有方法 ,不过不太推荐把 ,完全可以用结构体和方法 。
枚举和结构体都是值类型 ,在传递的时候都是以拷贝的方式。类是引用类型 ,传递的时候只是传递一个引用 。
2、类和结构体类 @H_404_4@Class 结构体 @H_404_4@struct 简单的定义
struct myPoint{ var x = 0; var y = 0;}class Person { var name:String?; var age:Int?; var p1 = myPoint(x: 1,y: 2); var p = myPoint(); }
这里定义了一个简单的结构体和类,类中定义了几个简单的属性 , 包括 一个结构体属性 ,给出了两种初始化的方法 。关于属性的声明可以去看 Swift详解之一 ——– 变量声明 。
Int,float , 数组 字典 等 都是值类型 后台都以结构体的方式实现
一般使用结构体的情况
如果创建了一个结构体的实例,并且将这个实例赋值给一个常量 则无法修改其属性 ,就算是变量属性也无法修改
let p1 = myPoint(x: 1,y: 1)
这里我尝试修改结构体中的变量x 报错 。
引用类型赋给常量,仍然可以改变其变量属性,所以类的实例可以赋值给一个常量
懒加载延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性。在属性声明前使用lazy来标示一个延迟存储属性。 (懒加载)
注意:必须将延迟存储属性声明成变量(使用var关键字),因为属性的值在实例构造完成之前可能无法得到。而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性。
看下官方给的例子。
class Dataimporter { /* Dataimporter 是一个将外部文件中的数据导入的类。 这个类的初始化会消耗不少时间。 */ var filename = "data.txt" // 这是提供数据导入功能}
class DataManager { lazy var importer = Dataimporter() //这里使用了懒加载 在第一次用到的时候才去创建这个实例 如果创建DataManager 就去创建Dataimporter 有可能并不需要这个实例,浪费内存和时间 var data = [String]() // 这是提供数据管理功能}
let manager = DataManager()manager.data.append("Some data")manager.data.append("Some more data")// Dataimporter 实例的 importer 属性还没有被创建
这里可以看到我们并没有使用Dataimporter , 所以在创建DataManager()的时候并不并不需要初始化Dataimporter ,所以我们使用懒加载在这时候就节省了内存的开支。
但是,如果被标记位lazy的属性 在没有被初始化的时候被多个线程访问 这时候 不能保证这个属性只被实例一次
我们可以通过下面的方式定义一个只读属性 。
var a = 1.2;var b:Double{ return a*4 }类型属性
不管这个类有多少个实例 ,它的类属性 只有一个 。
关键字 @H_404_4@static
struct myStruct{ static var height = 19.3}
可以直接通过结构体的名字或者类的名字来调用类型 属性@H_404_4@print(myStruct.height)
不过在类中有时候需要使用关键字@H_404_4@class ,来允许它的子类重写这个属性 。
class myClass { static let name = "zhangsan " static var age = 21 static var status: Int { return 1 } //在定义计算型属性的时候可以使用 关键字 class 来支持子类对父类进行重写 class var canOverrID: Int { return 10 }}
class sonClass: myClass { overrIDe static var canOverrID: Int { return 89 } //static let name = "zhangsan " //cannot overrIDe with a stored property 'name'}
这里我们子类可以重写@H_404_4@class 标记的类型属性 。
方法方法可以分成实例方法和类型方法 。
类、结构体、枚举都可以定义实例方法;实例方法为给定类型的实例封装了具体的任务与功能。类、结构体、枚举也可以定义类型方法;类型方法与类型本身相关联。
结构体和枚举可以定义方法 是swift和oc的一大区别
类型方法就是在func 前面加static 类有时候可能需要加class 。跟属性的用法是一样的,这里就不在实例 。
变异方法值类型的属性不能在实例方法中被修改,但是有时候你确实想修改过,这时候 你可以使用变异方法 。关键字 @H_404_4@mutating
struct Counter{ var count = 0 func getCount() ->Int{ return count } //因为值类型的属性不能在实例方法中被修改 这里使用了变异方法 mutating func increment() { count++ }}var c = Counter()print(c.count) // 0print(c.getCount()) // 0c.increment()print(c.count) // 1
变异方法可以给自己赋值
enum Level { case High,MID,Low mutating func next() { switch self { case .High: self = MID case .MID: self = Low default: self = High } }}var level = Level.Highlevel.next()print(level) //Level.MIDlevel.next()print(level) //Level.Low总结
以上是内存溢出为你收集整理的Swift详解之六----------------枚举、结构体、类全部内容,希望文章能够帮你解决Swift详解之六----------------枚举、结构体、类所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)