Swift-闭包理解 swift 逃逸闭包的作用

   2023-02-09 学习力0
核心提示:/* 闭包(Closures)* 闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。* 在Swift中的闭包与C、OC中的blocks和其它编程语言(如Python)中的lambdas类似。* 闭包可以捕获和存储上下文中定义的的任何常量和变量的引用。这就是所谓的变量和变
/* 闭包(Closures) 
 * 闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。 
 * 在Swift中的闭包与C、OC中的blocks和其它编程语言(如Python)中的lambdas类似。 
 * 闭包可以捕获和存储上下文中定义的的任何常量和变量的引用。这就是所谓的变量和变量的自封闭, 
 * 因此命名为”闭包“("Closures)").Swift还会处理所有捕获的引用的内存管理。 
 *  
 * 全局函数和嵌套函数其实就是特殊的闭包。 
 * 闭包的形式有: 
 * (1)全局函数都是闭包,有名字但不能捕获任何值。 
 * (2)嵌套函数都是闭包,且有名字,也能捕获封闭函数内的值。 
 * (3)闭包表达式都是无名闭包,使用轻量级语法,可以根据上下文环境捕获值。 
 *  
 * Swift中的闭包有很多优化的地方: 
 * (1)根据上下文推断参数和返回值类型 
 * (2)从单行表达式闭包中隐式返回(也就是闭包体只有一行代码,可以省略return) 
 * (3)可以使用简化参数名,如$0, $1(从0开始,表示第i个参数...) 
 * (4)提供了尾随闭包语法(Trailing closure syntax) 
 */  
   
 // 下面用Swift标准库中的sort方法来一步步简化闭包写法  
 // sort函数需要两个参数  
 // 参数一:数组  
 // 参数二:一个闭包:带有两个参数,这两个参数类型与数组中的元素类型相同,返回值是Bool  
 var names = ["Swift", "Arial", "Soga", "Donary"]  
   
 // 第一种方式:使用函数  
 func backwards(firstString: String, secondString: String) -> Bool {  
   return firstString > secondString // 升序排序  
 }  
 // 这里第二个参数,传了一个函数  
 // reversed is equal to ["Swift", "Soga", "Donary", "Arial"]  
 var reversed = sort(nams, backwards)  
   
 // 第二种方式:使用闭包方式  
 // 完整闭包写法是在花括号内有参数列表和返回值,用关键字in表明闭包体的开始  
 // (firstString: String, secondString: String) 闭包参数列表  
 // -> Bool 指明闭包返回值类型是Bool  
 // in关键字表明闭包体的开始  
 reversed = sort(names, { (firstString: String, secondString: String) -> Bool in  
    return firstString > secondString  
    })  
  
 // 这里可以进一步简化写法,因为闭包代码比较短,可以写到一行上  
 reversed = sort(names, { (firstString: String, secondString: String) -> Bool in return firstString > secondString})  
   
// 下面再进一步简化写法 :根据环境上下文自动推断出类型  
// 参数列表都没有指明类型,也没有指明返回值类型,这是因为swift可以根据上下文推测出  
// firstString和secondString的类型会是names数组元素的类型,而返回值类型会根据return语句结果得到  
reversed = sort(names, { firstString, secondString in return firstString > secondString})  
  
// 再进一步简化:隐式返回(单行语句闭包)  
// 因为闭包体只有一行代码,可以省略return  
reversed = sort(names, { firstString, secondString in firstString > secondString})  
  
// 再进一步简化:使用简化参数名($i,i=0,1,2...从0开始的)  
// Swift会推断出闭包需要两个参数,类型与names数组元素相同  
reversed = sort(names, { $0 > $1 })    
  
// 最简单的一种写法:使用操作符  
reversed = sort(names, >)      
      
      
/* 
 * 尾随闭包(Trailing Closures) 
 * 如果函数需要一个闭包参数作为参数,且这个参数是最后一个参数,而这个闭包表达式又很长时, 
 * 使用尾随闭包是很有用的。尾随闭包可以放在函数参数列表外,也就是括号外。如果函数只有一个参数, 
 * 那么可以把括号()省略掉,后面直接跟着闭包。 
 */   
// Array的方法map()就需要一个闭包作为参数  
let strings = numbers.map { // map函数后面的()可以省略掉  
  (var number) -> String in  
  var output = ""  
  while number > 0 {  
    output = String(number % 10) + output   
    number /= 10  
  }  
  return output  
}  
      
/* 捕获值 
 * 闭包可以根据环境上下文捕获到定义的常量和变量。闭包可以引用和修改这些捕获到的常量和变量, 
 * 就算在原来的范围内定义为常量或者变量已经不再存在(很牛逼)。 
 * 在Swift中闭包的最简单形式是嵌套函数。 
 */   
func increment(#amount: Int) -> (() -> Int) {  
  var total = 0  
  func incrementAmount() -> Int {  
    total += amount // total是外部函数体内的变量,这里是可以捕获到的  
    return total  
  }  
  return incrementAmount // 返回的是一个嵌套函数(闭包)  
}     
      
// 闭包是引用类型,所以incrementByTen声明为常量也可以修改total  
let incrementByTen = increment(amount: 10)   
incrementByTen() // return 10,incrementByTen是一个闭包  
// 这里是没有改变对increment的引用,所以会保存之前的值  
incrementByTen() // return 20     
incrementByTen() // return 30     
  
let incrementByOne = increment(amount: 1)  
incrementByOne() // return 1  
incrementByOne() // return 2      
incrementByTen() // return 40   
incrementByOne() // return 3 

 

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • swift 命令行工具初探
    亲爱的同学们好,今天我们要介绍这么一个东西。相信有过解释型语言(PHP,Ruby,等)使用经验的同学会更加熟悉,就是 Swift 也为我们提供了命令行运行工具,俗称 REPL。好了,我们进入正题,在安装好 Swift 开发环境的机器上,打开命令行,输入 swift 命令,就进
    03-16
  • [Swift]冒泡排序 | Bubble sort
    [Swift]冒泡排序 | Bubble sort
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)➤GitHub地址:https://github.com/strengthen/LeetCode➤原文
    03-08
  • [Swift] 自定义在 SwiftUI 中实现的可搜索的外观
    [Swift] 自定义在 SwiftUI 中实现的可搜索的外
    首先我找遍了,似乎找不到任何信息......(我遇到了许多根本不起作用的事情......)终于在详细的英文文献中找到了,我会保留下来,希望以后有机会。关于 SwiftUI 中的可搜索searchable是iOS15新增的易于实现的搜索字段。关于这种情况有一个参数placement,您
    03-08
  • [Swift] 检测 SwiftUI ScrollView 中的偏移量
    [Swift] 检测 SwiftUI ScrollView 中的偏移量
    首先你可以用ScrollViewReader做一些可以从iOS14使用的事情。但是,我不能做我想做的事情,所以我想我还能做些什么。再次,可重复使用我尝试过了。执行我将首先发布实现的图像。 (Swift Playgrounds 演示)您可以像这样根据滚动获取坐标。让我们看看实现。1.
    03-08
  • Swift3.0 UICollectionView 删除,拖动
    Swift3.0 UICollectionView 删除,拖动
    UICollectionView实现了一下常见的新闻分类.  附有效果图 近期一直在深入学习swift,实现了CollectionView item的头东与删除,用的都是系统的一些函数方法,看起来比较直观. 第一步:class HotViewController: UIViewController,UICollectionViewDelegate,UICo
    02-09
  • swift -懒加载创建view
     // 只有外界访问到headerView的时候才会去执行闭包, 然后将闭包的返回值赋值给headerView    // 注意: 一定要记住闭包后面需要写上(), 代表执行闭包    //懒加载创建UIView    lazy var headerView: UIView = {        let view = UIView()
    02-09
  • Swift--非常好用的适合局部的代码约束
    // 哪个控件的哪个属性等于(大于、小于)另外一个控件的哪个属性乘以多少再加上多少 eg:let widthContraint = NSLayoutConstraint(item: messageLabel, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLa
    02-09
  • iOS打包framework - Swift完整项目打包Framework,嵌入OC项目使用
    iOS打包framework - Swift完整项目打包Framewor
    场景说明:-之前做的App,使用Swift框架语言,混合编程,内含少部分OC代码。-需要App整体功能打包成静态库,完整移植到另一个App使用,该App使用OC。-所以涉及到一个语言互转的处理,以及一些AppDelegate的代码减除变化。 --------------------------------
    02-09
  • Swift -- 官方文档Swift-Guides的学习笔记
    在经历的一段时间的郁闷之后,我发现感情都是虚伪的,只有代码是真实的(呸)因为看了swift语法之后依然不会用swift,然后我非常作死的跑去看官方文档,就是xcode里自带的help》documentation and API reference其中的swift里的guide这里主要总结一下里面每一
    02-09
  • Swift - 进度条(UIProgressView)的用法
     1,创建进度条1234var progressView=UIProgressView(progressViewStyle:UIProgressViewStyle.Default)progressView.center=self.view.centerprogressView.progress=0.5 //默认进度50%self.view.addSubview(progressView); 2,设置进度,同时有动画效果1p
    02-09
点击排行