最近在温习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")
网友评论