【Swift】闭包(Closures)

闭包表达式(Closure Expressions)

嵌套函数 是一个在较复杂函数中方便进行命名和定义自包含代码模块的方式。当然,有时候撰写小巧的没有完整定义和命名的类函数结构也是很有用处的,尤其是在您处理一些函数并需要将另外一些函数作为该函数的参数时。

闭包表达式是一种利用简洁语法构建内联闭包的方式。 闭包表达式提供了一些语法优化,使得撰写闭包变得简单明了。 下面闭包表达式的例子通过使用几次迭代展示了sort(_:)方法定义和语法优化的方式。 每一次迭代都用更简洁的方式描述了相同的功能。

sort 函数(The Sort Function)

Swift 标准库提供了名为sort的函数,会根据您提供的用于排序的闭包函数将已知类型数组中的值进行排序。 一旦排序完成,sort(_:)方法会返回一个与原数组大小相同,包含同类型元素且元素已正确排序的新数组。原数组不会被sort(_:)方法修改。

下面的闭包表达式示例使用sort(_:)方法对一个String类型的数组进行字母逆序排序,以下是初始数组值:

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

sort(_:)方法需要传入两个参数:

  • 已知类型的数组
  • 闭包函数,该闭包函数需要传入与数组元素类型相同的两个值,并返回一个布尔类型值来表明当排序结束后传入的第一个参数排在第二个参数前面还是后面。如果第一个参数值出现在第二个参数值前面,排序闭包函数需要返回true,反之返回false

该例子对一个String类型的数组进行排序,因此排序闭包函数类型需为(String, String) -> Bool

提供排序闭包函数的一种方式是撰写一个符合其类型要求的普通函数,并将其作为ssort(_:)方法的参数传入:

func backwards(s1: String, s2: String) -> Bool {
    return s1 > s2
}
var reversed = names.sort(backwards)
// reversed 为 ["Ewa", "Daniella", "Chris", "Barry", "Alex"]

如果第一个字符串 (s1) 大于第二个字符串 (s2),backwards函数返回true,表示在新的数组中s1应该出现在s2前。 对于字符串中的字符来说,“大于” 表示 “按照字母顺序较晚出现”。 这意味着字母"B"大于字母"A",字符串"Tom"大于字符串"Tim"。 其将进行字母逆序排序,"Barry"将会排在"Alex"之前。

然而,这是一个相当冗长的方式,本质上只是写了一个单表达式函数 (a > b)。 在下面的例子中,利用闭合表达式语法可以更好的构造一个内联排序闭包。

闭包表达式语法(Closure Expression Syntax)

闭包表达式语法有如下一般形式:

{ (parameters) -> returnType in
    statements
}

闭包表达式语法可以使用常量、变量和inout类型作为参数,不提供默认值。 也可以在参数列表的最后使用可变参数。 元组也可以作为参数和返回值。

下面的例子展示了之前backwards函数对应的闭包表达式版本的代码:

reversed = names.sort({ (s1: String, s2: String) -> Bool in
    return s1 > s2
})

需要注意的是内联闭包参数和返回值类型声明与backwards函数类型声明相同。 在这两种方式中,都写成了(s1: String, s2: String) -> Bool。 然而在内联闭包表达式中,函数和返回值类型都写在大括号内,而不是大括号外。

闭包的函数体部分由关键字in引入。 该关键字表示闭包的参数和返回值类型定义已经完成,闭包函数体即将开始。

因为这个闭包的函数体部分如此短以至于可以将其改写成一行代码:

reversed = names.sort( { (s1: String, s2: String) -> Bool in return s1 > s2 } )

这说明sort(_:)方法的整体调用保持不变,一对圆括号仍然包裹住了函数中整个参数集合。而其中一个参数现在变成了内联闭包(相比于backwards版本的代码)

根据上下文推断类型(Inferring Type From Context)

因为排序闭包函数是作为sort(_:)方法的参数进行传入的,Swift可以推断其参数和返回值的类型。 sorted期望第二个参数是类型为(String, String) -> Bool的函数,因此实际上String,StringBool类型并不需要作为闭包表达式定义中的一部分。 因为所有的类型都可以被正确推断,返回箭头 (->) 和围绕在参数周围的括号也可以被省略:

reversed = names.sort( { s1, s2 in return s1 > s2 } )

实际上任何情况下,通过内联闭包表达式构造的闭包作为参数传递给函数时,都可以推断出闭包的参数和返回值类型,这意味着您几乎不需要利用完整格式构造任何内联闭包。

然而您仍然可以明确写出有着完整格式的闭包。如果完整格式的闭包能够提高代码的可读性,则可以采用完整格式的闭包。而在sort(_:)方法这个例子里,闭包的目的就是排序,读者能够推测除这个闭包是用于字符串处理的,因为这个闭包是为了处理字符串数组的排序。

单表达式闭包隐式返回(Implicit Return From Single-Expression Clossures)

单行表达式闭包可以通过隐藏return关键字来隐式返回单行表达式的结果,如上版本的例子可以改写为:

reversed = names.sort( { s1, s2 in s1 > s2 } )

在这个例子中,sort(_:)方法的第二个参数函数类型明确了闭包必须返回一个Bool类型值。 因为闭包函数体只包含了一个单一表达式 (s1 > s2),该表达式返回Bool类型值,因此这里没有歧义,return关键字可以省略。

参数名称缩写(Shorthand Argument Names)

Swift 自动为内联函数提供了参数名称缩写功能,您可以直接通过$0,$1,$2来顺序调用闭包的参数。

如果您在闭包表达式中使用参数名称缩写,您可以在闭包参数列表中省略对其的定义,并且对应参数名称缩写的类型会通过函数类型进行推断。 in关键字也同样可以被省略,因为此时闭包表达式完全由闭包函数体构成:

reversed = names.sort( { $0 > $1 } )

在这个例子中,$0$1表示闭包中第一个和第二个String类型的参数。

原文出处:http://wiki.jikexueyuan.com/project/swift/chapter2/07_Closures.html

时间: 2024-11-05 00:33:21

【Swift】闭包(Closures)的相关文章

Swift学习之十四:闭包(Closures)

* 闭包(Closures) * 闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值. * 在Swift中的闭包与C.OC中的blocks和其它编程语言(如Python)中的lambdas类似. * 闭包可以捕获和存储上下文中定义的的任何常量和变量的引用.这就是所谓的变量和变量的自封闭, * 因此命名为”闭包“("Closures)").Swift还会处理所有捕获的引用的内存管理. * * 全局函数和嵌套函数其实就是特殊的闭包. * 闭包的形式有: * (1)全局函数都是闭

Swift学习:闭包(Closures)

/* 闭包(Closures)* 闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值.* 在Swift中的闭包与C.OC中的blocks和其它编程语言(如Python)中的lambdas类似.* 闭包可以捕获和存储上下文中定义的的任何常量和变量的引用.这就是所谓的变量和变量的自封闭,* 因此命名为”闭包“(“Closures)”).Swift还会处理所有捕获的引用的内存管理.** 全局函数和嵌套函数其实就是特殊的闭包.* 闭包的形式有:* (1)全局函数都是闭包,有名字但不能捕获任何

The Swift Programming Language-官方教程精译Swift(8)闭包 -- Closures

闭包是功能性自包含模块,可以在代码中被传递和使用. Swift 中的闭包与 C 和 Objective-C中的 blocks 以及其他一些编程语言中的 lambdas 比较相似. 闭包可以捕获和存储其所在上下文中任意常量和变量的引用. 这就是所谓的闭合并包裹着这些常量和变量,俗称闭包.Swift会为您管理在捕获过程中涉及到的内存操作.  注意:如果您不熟悉 捕获 (capturing) 这个概念也不用担心,后面会详细对其进行介绍. 在 函数 章节中介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采

swift闭包 notes http://www.gittielabs.com

Swift Closureshtml, body {overflow-x: initial !important;}.CodeMirror { height: auto; } .CodeMirror-scroll { overflow-y: hidden; overflow-x: auto; } .CodeMirror-lines { padding: 4px 0px; } .CodeMirror pre { padding: 0px 4px; } .CodeMirror-scrollbar-f

Swift 闭包(六)

http://blog.csdn.net/huangchentao/article/details/32714185 闭包 Closures 1.闭包表达式 闭包表达式是一种利用简单语法构建内联包的方式,提供一些语法优化,使得闭包代码变得更加简单明了 1.1sort函数 Swift标准库提供了sort函数,将已知类型数组中的值进行排序,返回一个与原数组大小相等但元素已正确排序的数组sort函数需要传入两个参数: 1.已知类型的数组 2.传入两个跟数组相同类型参数的闭包函数,并返回一个布尔值告诉s

Swift闭包(Closure)

语法: { (parameters) ->return type in statements} 实例:采用函数实现: let names =["Chris", "Alex", "Ewa", "Barry", "Daniella"] funcbackwards(s1: String, s2: String) -> Bool { return s1 > s2 } var reversed =

SWIFt闭包

闭包的三种形式 1.全局函数是一个有名字但不会捕获任何值的闭包2.嵌套函数是一个有名字并且可以捕获其封闭函数域内值的闭包3.闭包表达式时一个利用轻量级语法缩写的可以捕获其上下文中变量或者常量值的没有名字的闭包 SWIFT闭包中的一些特点 1.利用上下文推断参数和返回值类型2.单表达式闭包可以省略return关键字3.参数名称简写4.Trailing闭包语法 闭包表达式 一般情况下我们采用如下方式使用sort 1 // Playground - noun: a place where people

swift闭包的另一种用法

这不是教程. 当你碰到函数参数需要传递一个闭包(closure)时,一般是可以直接这么传递的(假定无返回): // 教程一般教你在参数位置传递closure: someMethod(arg1, arg2, arg3: { args -> Void in //codes here }) // swift同时有一种“同步”的写法: someMethod(arg1, arg2){ args -> Void in //codes here } swift闭包的另一种用法

闭包(Closures)

浅析 JavaScript 中的闭包(Closures) 一.前言 对于 JavaScript 来说,闭包是一个非常强大的特征.但对于刚开始接触的初学者来说它又似乎是特别高深的.今天我们一起来揭开闭包的神秘面纱.闭包这一块也有很多的文章介绍过了,今天我就浅谈一下自己对闭包的的一些理解,希望能提供一点鄙陋的见解帮助到正在学习的朋友.该文章中能使用口语化的我将尽量使用口语化的叙述方式,希望能让读者更好理解,毕竟文章写出来宗旨就是要让人读懂.文章难免有不足之处还希望帮忙指出. 二.Javascript

Swift:闭包(Closures)

一. 基本概念 闭包(Closures)是自包括的功能代码块,能够在代码中使用或者用来作为參数传值. 在Swift中的闭包与C.OC中的blocks和其他编程语言(如C#)中的lambda, javascript中的函数嵌套等类似. 闭包能够捕获和存储上下文中定义的的不论什么常量和变量的引用. 这就是所谓的变量和变量的自封闭, 因此闭包还会处理全部捕获的引用的内存管理. 全局函数和嵌套函数事实上就是特殊的闭包. 闭包的形式有: (1)全局函数都是闭包.有名字但不能捕获不论什么值. (2)嵌套函数