Swift中的闭包,是一个自包含的函数代码块,可以再代码中传递和使用,作为对象来传送,作为函数来使用,类似于OC中的block函数
可以捕获和存储所在上下文中任意的常量和变量的引用,也就是闭合并且包裹着这些常量或变量,俗称为闭包;
在Swift中,会自动管理在捕获过程中涉及到的内存操作;
1、语法
{(参数:参数类型 。。。) ->返回值类型 in
//执行语句
}
2、具体使用:sort函数,是系统提供的一个排序函数,用于对数组中的元素进行排序,但是不会修改原来数组,(仅仅是排序输出)
let name = [“Asd”, “Jkas”, “Fdhk”, “Lsjd”]
//比较大小的排序函数
func prepare(para1: String, para2: String) -> Bool {
return para1 < para2
}
var newNames = names.sort( prepare) //实质上是将自定义的比较函数整个作为参数传给sort函数
3、使用闭包的语法-实现排序
newName = names.sort({ para1: String , para2 : String})-> Bool in {
return para1 < para2
})
4、根据上下文推断类型 - (闭包的简写)
在swift中,系统可以自动的推断参数和返回值的类型
newNames = names.sort({para1, para2 in
return para1 < para2
})
5、单表达式闭包隐试返回 - (闭包的简写)
可以通过隐藏return关键字来达到隐试返回的目的
newNames = names.sort({ para1, para2 in
para1 < para2
})
尾随闭包:(自己去了解)
三、枚举
在C语言中,枚举将枚举名和一个整形的值相对应,但是Swift中,枚举更加灵活,不必给每一个枚举成员提供一个值。如果给枚举值成员提供一个值,该值得类型可以是:字符串、字符、整形或浮点型。另外,枚举成员可以指定任何类型的相关值存储到枚举成员中;
1、语法,
定义枚举 enum关键字
enum Direction { //枚举名的第一个字母必须大写
case North //case 关键词表明新的一行成员值将被定义。
case West, case East , case South //多个成员值可以出现在同一行上,用逗号隔开
}
【注意:】1、和 C 和 Objective-C 不同,Swift 的枚举成员在被创建时不会被赋予一个默认的整型值。在上面的CompassPoints例子中,North,South,East和West不会隐式地赋值为了0,1,2和3。
2、枚举名字(例如CompassPoint和Planet)必须以一个大写字母开头。
2、枚举的使用
var direction = Direction.East;
direction = .South //枚举在被初次初始化之后,获取另外的值时,可以直接使用 “.” 语法调用
3、枚举与Switch语句配合使用
switch direction {
case .North:
case .South:
case .West:
case .east
}
//在判断一个枚举类型的值时,switch语句必须穷举所有情况。如果忽略了.West这种情况,上面那段代码将无法通过编译,因为它没有考虑到CompassPoint的全部成员。强制性全部穷举的要求确保了枚举成员不会被意外遗漏。
//当不需要匹配每个枚举成员的时候,你可以提供一个默认default分支来涵盖所有未明确被提出的枚举成员
四、类和结构体
1、定义:
类的定义:关键字 class
class Person {
var name = “” //定义属性
}
结构体定义:关键字 struct
struct Student {
var name = “” //定义属性
}
2、实例化:
类:Person 类的实例化 : var per = Person()
类的属性赋值:per.name = “墨觞”
print(“姓名:(per.name)”)
结构体:Student 实例化 :var stu = Student()
结构体的属性赋值:stu.name = “夜凰”
print(“姓名:(stu.name)”)
3、类与结构体的混合编程
struct Hand {
var number = 0
}
class Child {
var name = “”
var age = 0
//当类中包含自定义的类时,需要将包含的类型进行初始化
var hands : Hand = Hand() //将 结构体Hand 作为类型标注
}
var child = Child() //实例化Child类
child.name = “夜凰” //给属性赋值
child.age = 5
child.hands.number = 2 //可以直接通过“.语法”就可调用
4、逐一构造器
结构体具有逐一构造器,但是类没有,因为结构体是值类型,类是引用类型
struct Dog {
var name = “”
var age = 0
}
var dog = Dog() //普通实例化
逐一构造器:在实例化结构体的同时,对属性进行赋值。
var dog = Dog(name: “夜凰”, age: 12)
5、值类型
特点:当赋值给变量、常量、或函数时,实质上是 拷贝。
var dog1 = dog //拷贝关系
dog.name = “墨觞” //对原始数据进行更改,不影响被拷贝的类
在 Swift 中,所有的基本类型:整数(Integer)、浮点数(floating-point)、布尔值(Boolean)、字符串(string)、数组(array)和字典(dictionary),都是值类型,并且都是以结构体的形式在后台所实现。
在 Swift 中,所有的结构体和枚举类型都是值类型。这意味着它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制。
6、引用类型
与值类型不同,引用类型在被赋予到一个变量、常量或者被传递到一个函数时,操作的是做了指针的指向,其并不是拷贝。
class Cat {
var name = “”
var age = 0
}
var cat = Cat()
cat.name = “猫咪”
var cat1 = cat
cat.name = “小猫” //由于不是拷贝关系,原始文件被改变时,新生成的文件也会发生变化
类与结构体的相同点和不同点
相同点:
· 定义属性用于存储值
· 定义方法用于提供功能
· 定义附属脚本用于访问值
· 定义构造器用于生成初始化值
· 通过扩展以增加默认实现的功能
· 实现协议以提供某种标准功能
· 定义方式一样
不同点:
1、关键字不同, 类:class 结构体:struct
2、实例化时,结构体有逐一构造器,类没有
3、结构体是值类型,类是引用类型
联系:可以将结构体作为类型标注在类中使用,(混合编程)
类还有如下的附加功能:
· 继承允许一个类继承另一个类的特征
· 类型转换允许在运行时检查和解释一个类实例的类型
· 解构器允许一个类实例释放任何其所被分配的资源
· 引用计数允许对一个类的多次引用
注意: 结构体总是通过被复制的方式在代码中传递,因此请不要使用引用计数。
7、实例方法和类方法的使用
class Tiger {
var name = “”
var age = 0
//创建实例方法
func eat() {
print(“practice makes perfect”)
self.name = “tiger” //在实例方法中,self表示当前类的对象
}
func run( name: String) {
self.name = name //self可以区分属性和形参
}
//创建类方法 :通过关键字static或者class关键字标明
//在实例方法前面添加关键字,变为类方法
static func bark(){
print(“你好”)
}
}
//如何调用类方法和实例方法
//实例化
var tiger = Tiger()
//调用实例方法,通过对象调用
tiger.eat()
//调用类方法,通过类名直接调用
Tiger.bark()
类方法与实例方法的相同点与不同点
相同点:
1、实质上都是函数
2、都可以对类的属性进行修改
不同点:
1、声明时,类方法使用关键字:static或class ,实例方法不需要
2、调用时,实例方法只能通过类的对象调用,类方法可以通过类名直接调用
8、在值类型(结构体)中,修改属性
strut Student1 {
var number = 100
var grade = 2
//在值类型中,定义实例方法,并在实例方法中修改结构体的属性,需要使用关键字mutating
mutating func study() {
self.number = 60
}
//在实例方法中,直接对self进行修改
mutating func play() {
//使用逐一构造器
self = Student1(number: 20, grade: 5)
}
}
var stu1 = Student1()
stu1.play()
stu1.study()
9、类的继承
class Car{
var carName = “”
var price = 0.0
// 可以在父类的实例方法中,添加final关键字,设置此方法不被子类调用
func run(){
print(“奔跑吧,逗逼”)
}
}
//通过类的继承,子类可以继承父类所有的方法和属性,和OC一样,swift中不允许多继承
class AutoCar: Car {
var factory = “蓝翔”
}
var autoCar = AutoCar()
autoCar.carName = “玛莎拉蒂”
autoCar.price = 0.1
autoCar.run()
class Bicycle : Car {
//在子类中,如果要重写父类方法,需要用 override关键字进行标明
override func run() {
print(“奔跑吧,哈哈”)
}
}