视频:P17-24 日期:4.28/4.29
目录
P17:匿名函数作为函数的参数
函数类型作为函数的参数类型
import UIKit
/*例一,无参数返回值的匿名函数*/
//1 一般情况
func test() //被传入的test函数
{
print("test()函数,没有参数,没有返回值")
}
var a:() -> Void = test
a() //a是函数类型的变量,所以使用a变量,就相当于使用函数
//将函数类型作为参数
func test1(param:() -> Void) //param()是一个函数类型
{
param() //调用作为参数的param()函数
}
test1(param:test)
//2 直接不要test,把它作为一个匿名函数传入
test1(param: ({() -> Void in
print("test()函数,没有参数,没有返回值")
}))
/*例二,有参数返回值的匿名函数*/
print("--------------------------------")
//一般情况
func add(a:Int,b:Int) -> Int //被传入的add函数
{
return a+b
}
func sum(param:(Int,Int)->Int) -> Int
{
let value = param(1,2)
print("value = \(value)")
return value
}
print(sum(param:add))
//不要add函数,直接把它变为匿名函数传入
var value2 = sum(param: ({(a,b) -> Int in //这里的a和b直接做类型推断,不用具体标明
return a+b
}))
print(value2)
/*例三,数组排序*/
print("--------------------------------")
var array = [1,3,5,0,2,8]
//1 一般情况
func srt(a:Int,b:Int) -> Bool //被传入函数srt
{
if a < b
{
return true
}
else
{
return false
}
}
array.sort(by:srt)
print(array)
//2 不要srt函数,直接把它作为匿名函数传入
array.sort(by:{(a,b) -> Bool in
if a > b //倒序
{
return true
}
else
{
return false
}
})
print(array)
/*
test()函数,没有参数,没有返回值
test()函数,没有参数,没有返回值
test()函数,没有参数,没有返回值
--------------------------------
value = 3
3
value = 3
3
--------------------------------
[0, 1, 2, 3, 5, 8]
[8, 5, 3, 2, 1, 0]
*/
P18:函数作为返回值,内嵌函数
1.函数作为返回值
import UIKit
func play1(s:String) -> Int
{
let value = Int(s) ?? 0
return value*value
}
func play2(s:String) -> Int
{
let value = Int(s) ?? 0
return value*2
}
func test(param:Bool) -> (String) -> Int //返回一个参数是String返回值为Int的函数
{
return param ? play1:play2
}
var a = test(param:true)
var b = test(param:false)
//a和b都是函数
print(a("3"),b("222"))
/*
9 444
*/
2.内嵌函数
import UIKit
print("内嵌函数:")
//内嵌函数就是在函数里面定义函数然后实现调用
func test0(param:Bool) -> (String) -> Int //返回一个参数是String返回值为Int的函数
{
func play1(s:String) -> Int
{
let value = Int(s) ?? 0
return value*value
}
func play2(s:String) -> Int
{
let value = Int(s) ?? 0
return value*2
}
return param ? play1:play2
}
var c = test0(param:true)
var d = test0(param:false)
print(c("3"),d("222"))
/*
内嵌函数:
9 444
*/
P19:匿名函数的简写方式
import UIKit
//1 无参数无返回值
var a:() -> Void = ({() -> Void in
print("1-无参数无返回值-复杂版")
})
a()
print(type(of: a))
//
var b:() -> Void = {
print("1-无参数无返回值-简化版")
}
b()
print(type(of: b))
//
var c = {
print("1-无参数无返回值-巨简版") //类型推断啦
}
c()
print(type(of:c))
print("---------------------------")
//2 无参数无返回值的函数作为test的参数
func test(param:() -> Void )
{
param()
}
//
test(param: {() -> Void in
print("2-函数作为参数无返回值-复杂版")
})
//
test(param:
{
print("2-函数作为参数无返回值-简化版")
})
//
test{print("2-函数作为参数无返回值-巨简版")}
print(type(of: test))
print("---------------------------")
//3 Int为参数无返回值的函数作为test2的参数
func test2(param:(Int) -> Void)
{
param(10)
}
//
test2(param:{(value:Int) -> Void in
print(value)
})
//
test2(param:{(value) in
print(value)
})
//
test2{(value) in
print(value)
}
print("---------------------------")
//4 2个Int为参数无返回值的函数作为test2的参数
func test3(param:(Int,Int) -> Int) {
print(param(10,20))
}
//
test3(param: {(item1,item2) -> Int in
return item1+item2
})
//
test3(param: {return $0 + $1 })
test3(param: {$0 + $1 })
/*
1-无参数无返回值-复杂版
() -> ()
1-无参数无返回值-简化版
() -> ()
1-无参数无返回值-巨简版
() -> ()
---------------------------
2-函数作为参数无返回值-复杂版
2-函数作为参数无返回值-简化版
2-函数作为参数无返回值-巨简版
(() -> ()) -> ()
---------------------------
10
10
10
---------------------------
30
30
30
*/
P20:定义枚举,设置枚举值
import UIKit
enum TestEnum //枚举的名称
{
case A
case B
case C //3个枚举值
}
func play(param:TestEnum) //将枚举类型作为参数传入
{
if (param == TestEnum.A)
{
print("a")
}
else if (param == TestEnum.B)
{
print("b")
}
else if (param == TestEnum.C)
{
print("c")
}
}
play(param: TestEnum.C)
//
enum TeatEnum:Int //枚举需要定义类型,否则会报错
{
case A = 1
case B = 2
case C = 3
}
print(TestEnum.A) //打印出来的是枚举本身,不是它的值
print(type(of:TestEnum.A)) //testEnum
//print(TestEnum.A.rawValue)
//raw.Value 用不了不知道咋回事
/*
c
A
TestEnum
//1 //原本会输出具体值
*/
P21:枚举相关值,遍历枚举
1.枚举相关值
import UIKit
enum TestEnum
{
case name(String)
case age(Int)
case xy(Int,Int)
}
func play(param:TestEnum)
{
switch param
{
case TestEnum.name("hello"):
print("hello")
case TestEnum.age(10):
print(10)
case TestEnum.xy(3,4):
print(3,4)
default:
print("没有匹配")
}
}
play(param: TestEnum.name("hello"))
play(param: TestEnum.name("swift"))
play(param: TestEnum.age(22))
play(param: TestEnum.xy(1,2))
/*
hello
没有匹配
没有匹配
没有匹配
*/
2.遍历枚举
import UIKit
enum TestEnum:CaseIterable //CaseIterable是TestEnum的一个迭代器
{
case A
case B
case C
}
TestEnum.allCases
//拥有allCaeses属性->是一个数组
print(type(of: TestEnum.allCases))
//数组因此可以遍历
for item in TestEnum.allCases
{
print(item)
}
//或者
for index in (0..<TestEnum.allCases.count)
{
print(TestEnum.allCases[index])
}
/*
Array<TestEnum>
A
B
C
A
B
C
*/
P22:结构体定义使用
1.结构体
2.mutating关键字
import UIKit
//结构体
struct Student
{
var name = "unknown"
var age = 0
var score = 0.0
var ispass = false
static let schoolName = "家里蹲大学" //静态属性,可以直接用结构体的名称调用
//初始化init()
//空初始化器:
init() {
}
//非空初始化器:
init(name:String,age:Int,score:Double)
{
self.name = name
self.age = age
self.score = score
if (self.score < 60)
{
self.ispass = false
}
else
{
self.ispass = true
}
}
func getName() -> String{
return self.name
}
func getScore() -> Double
{
return self.score
}
func getIsPass() -> Bool
{
return self.ispass
}
//若要修改结构体中已经定义的值,需要加mutating关键字,否则会报错:
//Cannot assign to property: 'self' is immutable
mutating func setScore(score:Double)
{
self.score = score //要设置成新函数传进来的分数,否则就错了
if(self.score < 60)
{
self.ispass = false
}
else
{
self.ispass = true
}
}
}
//通常不建议在结构体中加定义函数,为了和类区别开
//下面进行实例化:
var a = Student()
print(a.getName())
//结果是unknown因为没有在实例化a的时候传值,因此用了第一个空的初始化器
//下面进行传值处理
var b = Student(name: "小明", age: 18, score: 90) //b是Student类型,直接通过类型推断,不用标注
print(Student.schoolName,"学校的", /*这里的静态常量schoolName只能用结构体Student来进行调用,否则报错*/
b.getName(),"同学的分数是:",b.getScore(),"他是否通过了考试:",b.getIsPass())
//或者直接调用变量,不调用函数
print(Student.schoolName,"学校的", /*这里的静态常量schoolName只能用结构体Student来进行调用,否则报错*/
b.name,"同学的分数是:",b.score,"他是否通过了考试:",b.ispass)
//调用setScore()进行修改
var c = Student(name: "小王", age: 18, score: 90) //b是Student类型,直接通过类型推断,不用标注
//小王同学的分数有问题,进行分数修改
c.setScore(score: 50)
print(Student.schoolName,"学校的", /*这里的静态常量schoolName只能用结构体Student来进行调用,否则报错*/
c.name,"同学的分数是:",c.score,"他是否通过了考试:",c.ispass)
/*
unknown
家里蹲大学 学校的 小明 同学的分数是: 90.0 他是否通过了考试: true
家里蹲大学 学校的 小明 同学的分数是: 90.0 他是否通过了考试: true
家里蹲大学 学校的 小王 同学的分数是: 50.0 他是否通过了考试: false
*/
3.结构体实例也是值传递
import UIKit
struct Test
{
var age = 10
}
var t1 = Test()
print("t1.age = ",t1.age)
var t2 = t1
print("t2.age = ",t2.age)
t2.age = 100 //改变t2.age的值,看看t1.age的值有没有改变
print("t1.age = ",t1.age)
print("t2.age = ",t2.age)
//发现t1.age=10,t2.age=100,说明结构体传递是传递值,不是传引用
/*
t1.age = 10
t2.age = 10
t1.age = 10
t2.age = 100
*/
4.常量和变量实例
import UIKit
//常量变量问题
struct Test
{
var a = 123
let b = 12345
}
var t = Test()
print("t.a = ",t.a,"t.b = ",t.b)
//不能改变t.b的值,因为b属性是let常量
t.a = 10
//t.b = 10 //Cannot assign to property: 'b' is a 'let' constant
print("t.a = ",t.a,"t.b = ",t.b)
print("----------------------")
//同样的,假如在定义实例的时候就将之定义为let,那即使属性a是var也不能修改值
let t2 = Test()
// t2.a = 10 Cannot assign to property: 't2' is a 'let' constant
// t2.b = 10 // Cannot assign to property: 'b' is a 'let' constant
/*
t.a = 123 t.b = 12345
t.a = 10 t.b = 12345
----------------------
*/
P23:计算属性的使用
1.计算属性set和get
set 和 get 用来定义属性的,比如name
2.只读属性
即设置为private,无法外部调用
import UIKit
struct Person
{
private var value = "value" //private私有变量
var name:String
{
set(param) //或者去掉(param)
{
value = "valueset" //改变了value的值,在后面调用的时候value变了
print ("set - "+param) //将param改为newValue,是一样的
}
get //get的作用就是进行set之外的value的使用,return加字符串之类的
{
print("get")
return value + " ios"
}
}
init()
{
}
}
var person = Person()
person.name = "hhh" //设置set,传入”hhh“参数
//若没有set()方法,则无法设置值
person.name //调用get函数
print(person.name)
/*
set - hhh
get
get
valueset ios
*/
set可以不写,可以在init()中进行初始化,可以不用写set后面的:(param)
import UIKit
struct Person
{
private var value = "value" //private私有变量
var name:String //如果设置为private,则无法用set和get
{
set//去掉(param),将param改为newValue,是一样的
{
value = newValue //原来是param
}
get //get的作用就是进行set之外的value的使用,return加字符串之类的
{
return value
}
}
init(name:String)
{
self.name = name
}
}
var person = Person(name:"hhhh") //必须要传入参数,因为init有参数啊啊啊啊
print(person.name)
/*
hhhh
*/
例子:计算面积
import UIKit
//应用例子
struct GraphArea
{
private var circleArea:Double = 0
private var squareArea:Double = 0
private var original_radius:Double = -1 //存储最新半径,开始设置为-1
var radius:Double
{
set(radius)
{
circleArea = Double.pi * (radius * radius )
let diam:Double = radius * 2
squareArea = diam * diam //4pi方
original_radius = radius //半径
}
get
{
return original_radius
}
}
init(radius:Double)
{
self.radius = radius
}
func getCircleArea() -> Double
{
return self.circleArea
}
func getSquareArea() -> Double
{
return self.squareArea
}
}
//所以这个代码在干啥,看下面:
var area = GraphArea(radius:10) //首先在创建GraphArea实例的时候就传入一个半径参数,看init
print("半径 = " + String(area.radius)) //返回area的半径
print("圆形面积 = " + String(area.getCircleArea()))
print("正方形面积 = " + String(area.getSquareArea()))
print("--------------------------------------------")
area.radius = 20 //修改半径,每次重设半径值的时候,set代码块都会被执行,也就是所有面积都会被重新计算
print("半径 = " + String(area.radius)) //返回area的半径
print("圆形面积 = " + String(area.getCircleArea()))
print("正方形面积 = " + String(area.getSquareArea()))
/*
半径 = 10.0
圆形面积 = 314.1592653589793
正方形面积 = 400.0
--------------------------------------------
半径 = 20.0
圆形面积 = 1256.6370614359173
正方形面积 = 1600.0
*/
P24:属性观察的使用willSet和didSet
属性观察
import UIKit
//属性观察,即属性监听
struct Person
{
var name:String = "unknow"
{
willSet(new_value) //默认属性是newValue,可以不用传值进去
{
print("willSet - " + new_value)
}
didSet(old_value) //默认属性是newValue,可以不用传值进去
{
print("didSet - " + old_value)
}
}
}
var person = Person()
person.name = "hello" //改变了name的值,看看会出现什么情况
//结果进行了属性新旧的监听,一旦这个值改变,就可以知道
person.name = "hello" //哪怕新改变的值和原来新的值一样,一样会监听改变
print(person.name) //直接调用最新的值
/*
willSet - hello
didSet - unknow
willSet - hello
didSet - hello
hello
*/