Swift2.0 数据结构:元组,枚举,结构体
2017-02-20 本文已影响17人
王家薪
标签(空格分隔): IOS-Swift
[toc]
概念介绍
名称 | 说明 |
---|---|
元组 | 元组是在swift中特有的一种数据结构,它可以储存任意类型的值,是一种很轻量的结构使用起来非常方便轻巧 |
枚举 | swift中的枚举值由hash表的方式存放的,如果不明确的指定.它也不会被隐式转换为一系列的Int值 |
结构体 | 将不同的数据类型整合到一起构建出一个新的结构,就是结构体. |
元组
swift中的元组,主要作用就是将一些不同类型的数据整合到一起,有点类似结构体,但是使用起来更加的轻便,不需要事先声明结构可以直接创建任意长度的结构.
基本使用
//普通方式创建
let ice = ("a",1,"b")
//取值
let a = ice.0 //通过下标取值 从0开始
print(a)
let (c,d,e) = ice //通过创建变量接收值
print(c + "|" + String(d) + "|" + e)
//忽略 如果不想接受某个值 可以使用'_'符号来忽略这个值
let (name,age,_) = ice
print(age)
为了增加代码的可读性我们可以为元组的数据设定名称
let man = (name:"wang",age:18)
print(man.name) //设定参数名称后可以使用打点调用值 是不是越来越像结构体了?
个人理解
元组在我看来就是一种简易的结构体,随时使用随时创建结构,创建时便赋值了,不会出现空值.使用元组作为模型储存数据更加的安全,节约空间.
枚举
枚举的作用可以使我们为一个参数指定其值的范围.并为每个值赋予有意义的名称,极大的提高了大妈的可读性.swift中的枚举更加的强大,在swift中,枚举的值并不是一个真实的值,它仅仅代表着一个不同的唯一的值.当然,也可以手动指定枚举值的类型,包括但不仅限于Int
基本使用方法
//声明一个枚举类型
enum ServerStart {
case Connection
case Break
}
//使用
let saveStart = ServerStart.Break //创建一个枚举类型,值为Break
print(saveStart) //输出枚举的值 结果为:Break 并非想C类型枚举中是个整数
//使用分支进行判断
switch saveStart {
case .Break:
print("The is break")
case .Connection:
print("The is connection")
default: break
}
输出结果:
//The is break
在C语法中常用数值来代替枚举值或者用整数和枚举值进行比较,但是在swift中如果想这样做,需要为枚举指定类型,而会被默认转换成由0开始的整数
enum Friender:Int { //注意,这里在声明处加了一个Int类型声明,表示枚举的值为Int类型的
case kid = 12
case adult = 30
}
//这样我们就可以使用rawValue属性取出里面的值
let a = Friender.adult
print(a.hashValue) //输出hash值这个值是枚举的唯一标识,从0开始
print(a.rawValue) //输出raw值,这个值是声明的时候设定的
下面就是一些比较有意思的功能了,在swift中枚举值还可以储存一些附加值.
//声明
enum names {
case English(Number:Int,Name:String) //可以带一个参数也可以带多个参数,类型也可以不同
case Chinese(String) //参数的名称也可以不写 只需要声明要储存值的类型即可
}
//使用
let a = names.Chinese("asd")
//目前只知道了在switch中如何使用枚举值存储的属性,不晓得用什么类型来接受,知道的小伙伴可以联系QQ:326354777
switch a {
case .Chinese(let name):
print(name)
case .English(let number, let name):
print(name)
}
更多功能
除了可以储存值,还可以使用方法.(这TM不就成类了),不止是枚举 结构体中也可以有自己的独有方法,看Int等基本类型就清楚了.在Swift中基本类型都是由结构体存储的,他们分别封装了不同的方法.比如Int值的
toIntMax()
方法
//声明
enum People {
case white
case balck
func description() -> String {
return String(self) //self表示枚举自身
}
}
//使用
let man = People.white
print(man.description())
如果在方法内需要改变枚举自身的值则需要将方法声明成无法被常量调用的类型,可以使用关键字
mutating
enum People {
case white
case balck
func description() -> String {//任何类型都可以调用
return String(self)
}
mutating func aa(){ //只有使用var关键字声明的枚举才可以调用这个方法
self = .balck
}
}
结构体
在swift中,结构体和类很难区分,他们都有属性,方法,甚至使用方法都很接近,下面是一个区分表
类和结构体的区别
功能 | Class | Struct |
---|---|---|
继承 | 是 | 否 |
协议 | 是 | 是 |
扩展 | 是 | 是 |
属性是否可空 | 是 | 否 |
类方法 | 是(class) | 是(static) |
静态属性 | 需要单利模式 | 是 |
析构函数 | 是 | 否 |
构造函数 | 是 | 是 |
通知 | 是 | 否 |
代理 | 是 | 否 |
内存释放 | 是 | 否 |
结构体的储存性质
结构体在swift中是作为一个值存在的,也就是说,如果你将一个结构体的值赋值给另外一个结构体变量,那么就有了两个相同的值存在于不同的变量中,修改其中一个变量的值不会影响另外一个值.这个和类是不同的,使用类对象的时候如果将对象赋值给另外一个对象,这个对象并没有变成两份,其中一个对象改变另外一个对象也会跟着变化.所以说.结构体是无法使用通知和代理的.
什么时候使用结构体?
结构体和类非常相似,怎么选择合适的来使用呢?首先看他们的功能区别,类的功能要比结构体强的多,所以大多数我们都选择使用类,那么什么情况下可以考虑使用结构体呢?
- [ ] 结构体不能使用通知和代理,所以如果想跨界传参就放弃结构体吧.
- [ ] 结构体不能支持继承,所以在扩展性上要差,当属性以后可能会扩展的情况下也不可以用结构体
- [ ] 结构体赋值属于复制操作,而不是引用,所以当需要共用属性的时候不可以用
- [x] 当需要将一些基本类型组合在一起的时候我们可以使用结构体,相比类更加轻巧方便
- [x] 使用更好理解的名称定义基本类型,为基本数据增加方法和初始化功能.
基本使用方法
//创建一个结构体
struct JXPeople{
var name:String = "12" //可以为属性设置默认值也可以不设置
var age:Int //结构体没有可空属性,虽然没有设置值但是在创建时必须赋值,而类可以使用'?'来声明可空属性
var height:Float
func aaaaa() { //实例方法,和类没有区别
print("实例方法")
}
static func bbbbb(){ //静态方法使用关键字static,等同于类的类方法.
print("静态方法")
}
}
//结构体的使用
//初始化方法,因为我没没有写初始化方法,所以系统自动生成一个初始化方法
let man:JXPeople = JXPeople.init(name: "sd", age: 5, height: 12.0 )
print(man.name)//输出name
man.aaaaa()//调用对象方法
JXPeople.bbbbb()//调用静态方法
输出结果:
sd
实例方法
静态方法
扩展可重写
我们还可以为结构体扩展方法和重写初始化方法
struct JXPeople{
var name:String = "12"
var age:Int
var height:Float
init(){//重写初始化方法,这个方法调用后必须保证结构体的所有属性都不为空
self.name = "asd"
self.height = 12.0
self.age = 1
}
}
//扩展方法
extension JXPeople{ //扩展方法不可以扩展属性
init(_age:Int,_height:Float){ //这是扩展的一个初始化方法
self.age = _age
self.height = _height
}
mutating func setName(_name:String){
//mutating表明此方法只有var声明的对象才可以调用,在方法内更改属性值必须设置mutating
self.name = _name
}
}
注意:在OC中不能为UIView的Frame属性直接设置X或Y,称之为深度赋值错误.但是在Swift中则没有这个错误.可以直接设置X或Y