swift 函数闭包专题(超容易理解篇)

2020-01-03  本文已影响0人  帅气的阿斌

最近在温习swift的闭包,发现官方文档基本是意译过来的,什么闭包、逃逸...反正就是取一些你不懂的名词,所以自己写了下关于闭包的代码以及注释,完全用了自己个人的程序员思想写的文档,所以应该更浅显易懂~

本文适用于那些看了官方文档但仍然无法理解的小伙伴

本文适用于那些看了官方文档但仍然无法理解的小伙伴

本文不适用于完全还没学闭包的小伙伴

本文仅用于辅助理解闭包,并不适用于带你从零入门闭包

个人水平有限,有错误请指教 勿喷~

个人水平有限,有错误请指教 勿喷~

函数基础:作为返回值、参数...等用法

/*闭包通用表达式语法
  { (parameters) -> (return type) in
    statements
  }
 */

//声明函数的另一种方式: 闭包代码块 可替代一般的函数声明 func funcname(...){...}
let fuuunc = {(para1: String, para2: String) -> String in
    print("dddddd")
    return "dddddd"
}
fuuunc("1", "2")

//关于函数作为返回值
//=>函数作为返回值,那函数类型是什么?
/*y声明一个函数的一般形式
 func funcName (para: Int) -> Int {}
 */
//我们可以理解为 func funcName = (para: Int) -> Int {}
//funcName是函数名 右边是函数执行块
//也就是说函数其实就是 = 号右边的部分,{}是函数体部分,那我们就可以简单理解可以把 (para: Int) -> Int 看成是函数体的类型,是用来修饰{}的
//结论:函数类型可以用 (parameters) -> (return type) 表示
//e.g (Int) -> String 表示的是 一个为Int的参数返回值为string的函数
func returnFunc() -> (Int) -> String{
    func beReturnedFunc(a: Int) -> String{
        return "ha"
    }
    return beReturnedFunc(a:)
}

//函数类型可以用 (parameters) -> (return type) 表示
//尾随闭包:实际就是函数作为参数传递 someClosure为参数名; () -> Void表示该参数是一个参数为空,无返回值的参数类型
func tailClosure(para: String, someClosure: () -> Void){
    print(para)
    someClosure()
}
tailClosure(para: "ha") {
    print("闭包执行")
}

//全参数尾随闭包示例
func tailClosure2(para1: String, para2: String, someFunc: (_ sPara1: String, _ sPara2: String) -> ( r1: String, r2: String)) -> ( r3: String, r4: String){
    print("para1 = " + para1 + " para2 = " + para2)
    var someFuncResult = someFunc("闭包参数1", "闭包参数2")
//    ❌Cannot convert return expression of type '(r1: String, r2: String)' to return type '(r3: String, r4: String)'
//    return someFuncResult
    
//    修改成以下返回则正确
    return (someFuncResult.r1, someFuncResult.r2)
}

//或者闭包函数和函数返回值 名保持一致
func tailClosure3(para1: String, para2: String, someFunc: (_ sPara1: String, _ sPara2: String) -> ( r1: String, r2: String)) -> ( r1: String, r2: String){
    print("para1 = " + para1 + " para2 = " + para2)
    var someFuncResult = someFunc("闭包参数1", "闭包参数2")
    return someFuncResult
}

var resultValue = tailClosure2(para1: "普通参数1", para2: "普通参数2") { (str1, str2) -> (r1: String, r2: String) in
    print("闭包执行")
//    注意!!!!这里是闭包的返回值 不是 tailClosure2 函数的返回值!!!!!!!
    return ("闭包返回参数1", "闭包返回参数2")
}

print(resultValue)

//关于闭包是否 对常量是值复制还是地址复制呢
//函数接收基本数据类型的数据后 参数为 let类型 不可改变!!!
//var valuetemp = 10
////❌Cannot assign to value: 'para' is a 'let' constant
//let closureGetValue = { (para: Int) -> Int in
//    para = para + 1
//    return temp
//}
//closureGetValue(valuetemp)

逃逸闭包

//逃逸闭包 概念:函数作为参数传入到另一个函数中,但是在另一个函数中并没有直接调用,外部变量 funtempfinal 又引用了该函数,在 mainFunc 调用完毕后 又继续使用 funtempfinal 再进行调用,此时就必须使用 @escaping 来修饰 否则编译报错
//简单来说就是函数C 作为参数传入函数A 但是函数A并没有调用函数C,而是使用了外部的变量又引用了函数C,函数A执行完后又通过外部变量调用函数C
//于此对比的是 para 参数,普通类型的值传递则不需要什么逃逸~
var funtempfinal: () -> Void = { () -> Void in
    print("初始化 funtempfinal 变量")
}

var outPara: String? = nil

func mainFunc( para: String, func1: @escaping () -> Void ){
    print("mainFunc")
    outPara = para
    funtempfinal = func1
}

mainFunc(para: "para") {
    print("func1")
}
//在 mainFunc 调用后,再调用
funtempfinal()
print(outPara)

自动闭包

//最简单的一个代码块
let autoClosure = {
    print("666")
}
var b = autoClosure()
//自己实现一个 assert 断言
//assert(<#T##condition: Bool##Bool#>, <#T##message: String##String#>)

// 参照assert用法 定义两个参数 condition 与 message    condition为函数作为参数传入,表达是应是判断句,即表达式要返回bool值
func customAssert( _ condition: () -> Bool, _ message: String ){
    if condition() {
        print("正确")
    }else{
        print("错误")
        print(message)
    }
}

//一般调用
customAssert({ () -> Bool in
    
    return 1 > 2
    
}, "1<2")

//自动闭包调用 自动闭包的效果=> !不接受任何参数 表达式的值作为结果返回!  {1>2} 则表示无参函数,且表达式 1>2 的结果值作为返回值返回
customAssert({1>2}, "1<2")

//到这里基本实现了类似assert的效果 但是还是差点 多了个 {}
//@autoClosure 简单来说 @autoclosure 就是把传入的表达式自动打包成闭包(自己加上{})
func betterCustomAssert( _ condition: @autoclosure () -> Bool, _ message: String ){
    if condition() {
        print("正确")
    }else{
        print("错误")
        print(message)
    }
}

//至此我们实现了和assert一模一样的断言
betterCustomAssert(1>2, "1<2")

上一篇 下一篇

猜你喜欢

热点阅读