枚举enum和结构体与C中的类似,主要用于别名定义一些有限的类型和一些复杂的数据结构。但是在swift中的枚举呢除了具有基本的类型限制和别名使用外还可以进行继承,遵守协议。
结构体struct和后续的类相似,但是结构体是一个值拷贝的数据类型。
一:枚举
1:枚举的声明
声明一个枚举需要使用关键字enum;
enum Toward{
case Forward
case Back
case Left
case Right
}
case 关键字表示增加一个枚举定义值,当然,还可以把所有的枚举值写在一行当中。
enum Toward{
case Forward , Back , Left , Right
}
2:枚举值
枚举元素只有在指定了类型之后才可能有原始值,可以用 toRaw() 的方法获取枚举的原始值。
例如:
let goTo = Toward.Left //获取枚举中的某个定义的值
print(goTo.toRaw()) //错误的。因为枚举中并没有对每个元素赋相应的值。
在以上的定义中,四个枚举值并没有被赋具体的值(这与C语言中不同的地方)
如果要给枚举中定义的所有的枚举值赋值,需要指定枚举的类型。
enum Toward:Int {
case Forward , Back , Left , Right
}
这时,枚举中的四个元素就被默认赋值从0 开始的整数。
let goTo = Toward.Left
print(goTo.toRaw())
//输出为2
也可以手动给每个枚举元素赋值
enum Toward:Int {
case Forward = 2, Back , Left = 20 , Right
}
当给某一个元素赋值后,后面的元素会根据该元素的值依次赋值。
let goTo = Toward.Back
print(goTo.toRaw())
//输出为3
print (Toward.Right.toRaw())
//输出为21
在swift中,枚举还可以被指定为其他类型,例如:String
enum Toward:String {
case Forward = “a”, Back = “b”, Left = “K” , Right = “F”
}
print (Toward.Right.toRaw())
//输出F
注意咯:如果指定枚举的类型为非Int,需要给每个枚举元素指定值,并且每一个值都必须是唯一的。像下面这样就有问题。
enum Toward:Double{
case Forward = 1.2
case Back = 1.2 //错误,因为1.2这个值已经存在
case Left = 2.5
case Right
//错误,因为这个枚举被指定为Double类型,必须给每一个元素指定值
}
3:通过 fromRaw() 方法可以由原始值得到枚举中对应的定义元素
enum Toward:Int {
case Forward = 2, Back , Left = 20 , Right
}
let toDirect = Toward.fromRaw(21)
//这里 toDirect 的类型是可选Toward,因为在枚举定义中不一定存在原始值为21的成员,此时 toDirect 的值为 Toward.Right
4:枚举的使用方法
枚举使用的场景较多,但是用法相对单一,一般都是用来表示一组相互关联的情况,或者数值。
//定义一个枚举
enum TowardEvent {
case TouchUpInSide
case TouchDown
case DoubleClick
}
//定义一个事件,并指定其类型为TowardEvent
var event:TowardEvent
//定义event的事件类型为单击
event = TowardEvent .TouchUpInSide
//处理事件
switch event {
case.TouchUpInSide:
print(:按钮被单击")
case.TouchDown:
print("按钮被按下")
case.DoubleClick:
print("按钮被双击")
}
//输出:按钮被单击
在switch-case中必须覆盖所有枚举的成员情况。如果某些情况不需要单独处理,则必须使用Default进行处理。
switch event {
case.TouchUpInSide:
print(:按钮被单击")
case.TouchDown:
print("按钮被按下")
Default:
print ("其他情况")
}
二、结构体
结构体是用来保存一个对象或者说一种事物的一组信息,例如说:一个学生,有学号,姓名,性别等属性。结构体与枚举不同,一个变量被声明为某一个枚举类型后,它的值仅仅是枚举类型中所定义的一组值中的一个,而一个变量声明为结构体后,就包含了结构体中定义的所有值。
1:结构体的声明和定义
可以用 struct 关键字来声明一个结构体;
struct Student {
var sID : Int ; // 学号
var sName : String; // 姓名
var sSex : Bool; // 性别
var sPhone : String; // 电话
}
在结构体声明时,也可以不指定属性的类型,而是需要给每一个属性赋值,并通过类型识别获取所有属性的类型。
struct Student {
var sID = 0
var sName = " "
var sSex = true
var sPhone = " "
}
2:空参构造方法和全参构造方法 2.1:空参构造方法 var Li = Student ()
结构体的成员变量必须有初始值,所以用上面的方法定义一个结构体不能使用空参构造方法,因为没有初始值,这样会报错。
2.2:全参构造方法 var Li = Student(sID:12 , SName : "王八", sSex : true , sPhone : "13131313131");
全参构造方法中必须对结构体中的每一个属性进行赋值,但这里的字段必须按照顺序进行,而且构造方法里面的参数名字和字段名字要完全相同。 不管用哪一种构造方法,都可以用全参构造方法,但使用全参构造方法会把结构体默认的属性值覆盖掉。
3:结构体的赋值和取值
结构体可以属性名称对结构体实例属性进行访问。这里的结构和字段之间通过“ . ”语法来访问。
例如: print (Li.sName) // 输出为:王八
在结构体实例化后,可以对属性的值进行赋值和修改。
var Zhang = Student(); Zhang.sName = “李四” print (Zhang.sName)
// 输出:李四
对结构体属性进行赋值后,该属性的值会被新值所覆盖。
var Zhang = Student(); Zhang.sName = “张三” Zhang.sName = “王五” print (Zhang.sName) // 输出:王五
4:结构体的嵌套
在结构体的定义是可以嵌套的,比如:一个学生在一个班级上课,班级又是另外一个结构体,每个班级都有对应的老师。
现在,定义一个老师结构体。
struct Teacher{
var tID = 0 var tName = “”
}
再定义一个班级结构体。
struct ClassRoom{
var ClassId = 0
var ClassName = “”
var ClassCharge = Teacher() //老师
}
定义一个学生结构体。
struct Student{
var stuId = 0
var ClassInfo = ClassRoom()
var stuName = " "
var stuSex = true
var stuPhone = " "
}
现在定义一个学生,对学生的信息进行赋值:
var Zhang = Student()
Zhang.stuName = “张三”
Zhang.ClassInfo.ClassName = "Swift语言"
Zhang.ClassInfo.ClassCharge.tName = "马云"
print ("学生:"+Zhang.stuName +"班级:"+Zhang.ClassInfo.ClassName+"老师:"+Zhang.ClassInfo.ClassCharge.tName)
//输出:学生:张三 班级:Swift语言 老师:马云
在结构体的嵌套中,对实例属性的访问使用链式方式进行访问。也就是结构体中可以一层一层的进行嵌套读写操作。
5:结构体是值拷贝类型
值类型是相对于引用类型来说的,是指两个结构体实例变量之间进行赋值时,是对结构体所有内容进行内容拷贝。
var Ma = Zhang
Ma.stuName = "马化腾"
print(Ma.stuName)
print(Zhang.stuName)
//输出:
//马化腾
//张三
*****************************************************************************************************************************************886