【Swift编程基础】P17-24

视频:P17-24 日期:4.28/4.29


目录

P17:匿名函数作为函数的参数

函数类型作为函数的参数类型

P18:函数作为返回值,内嵌函数

1.函数作为返回值

2.内嵌函数

P19:匿名函数的简写方式

P20:定义枚举,设置枚举值

P21:枚举相关值,遍历枚举

1.枚举相关值

2.遍历枚举

P22:结构体定义使用

1.结构体

2.mutating关键字

3.结构体实例也是值传递

4.常量和变量实例

P23:计算属性的使用

1.计算属性set和get

2.只读属性

P24:属性观察的使用willSet和didSet

属性观察

 


 

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
*/

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张小怪的碗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值