swift闭包和闭包函数 – Swift最新教程

上一章Swift教程请查看:swift枚举类型

Swift中的闭包类似于以块形式组织的自包含函数,可以在任何地方调用,比如C语言和Objective C语言。函数中定义的常量和变量引用被捕获并存储在闭包中。函数被认为是闭包的特殊情况,它有以下三种形式

全局函数 嵌套函数 闭包表达式
有个名字,但不捕获任何值 有个名字,从封闭函数捕获值 未命名闭包从相邻块捕获值

Swift 语言中的闭包表达式遵循crisp、optimization和轻量级语法风格,包括。

  • 从上下文推断参数和返回值类型。
  • 从单表达式闭包中隐式返回。
  • 简写参数名和
  • 闭包的语法

语法

下面是定义闭包的通用语法,它接受参数并返回数据类型

{
    (parameters) −> return type in
    statements
 }

下面是一个简单的例子:

let studname = { print("Welcome to Swift闭包") }
studname()

下面的闭包接受两个参数并返回一个Bool值:

{     
    (Int, Int) −> Bool in
    Statement1
    Statement 2
    ---
    Statement n
 }

下面是一个简单的例子:

let divide = {
    (val1: Int, val2: Int) -> Int in 
    return val1 / val2 
 }
 
 let result = divide(200, 20)
 print (result)

闭包表达式

嵌套函数提供了一种命名和定义代码块的方便方法,而不是表示整个函数声明和名称构造用于表示较短的函数,通过闭包表达式用有重点的语法在清晰的简短语句中表示函数。

升序排序程序

对字符串进行排序是通过Swift
保留函数“sorted”实现的,该函数在标准库中已经可用,该函数将对给定的字符串按升序排序,并返回新数组中的元素,其大小和数据类型与旧数组中提到的相同,旧的数组保持不变。

  • 在已排序的函数中有两个参数
  • 已知类型的值表示为数组。

数组内容(Int, Int)和返回一个布尔值(Bool)如果数组排序正确,它将返回真值,否则它将返回假。

写入一个带有输入字符串的普通函数并将其传递给已排序的函数,以将字符串排序为新的数组,如下所示

func ascend(s1: String, s2: String) -> Bool {
   return s1 > s2
}

let stringcmp = ascend(s1: "Swift", s2: "great")
print (stringcmp)

函数对数组进行排序是声明为字符串数据类型和它的返回类型和布尔提到,比较两个字符串,按升序排序并存储在一个新的数组,如果成功执行的排序函数将返回一个真正价值还将返回false。

闭包使用−表达式语法

  • 恒定的参数,
  • 可变参数,
  • inout参数。

闭包表达式不支持默认值,还可以使用可变参数和元组参数类型和返回类型。

let sum = {
    (no1: Int, no2: Int) -> Int in 
    return no1 + no2 
 }
 
 let digits = sum(10, 20)
 print(digits)

函数语句中提到的参数和返回类型声明也可以由带’in’关键字的内联闭包表达式函数表示。一旦声明参数和返回类型‘in’关键字被用来表示闭包的主体。

单表达式隐式返回

这里,已排序函数的第二个参数的函数类型清楚地表明闭包必须返回一个Bool值。因为闭包的主体包含一个返回Bool值的表达式(s1 > s2),所以不存在歧义,可以省略return关键字。

要返回表达式闭包中的单个表达式语句,其声明部分省略了’return’关键字。

var count:[Int] = [5, 10, -6, 75, 20]
let descending = count.sorted(by: { n1, n2 in n1 > n2 })
let ascending = count.sorted(by: { n1, n2 in n1 < n2 })

print(descending)
print(ascending)

已知类型闭包

考虑两个数字的加法。我们知道加法将返回整数数据类型。因此,已知的类型闭包被声明为-

let sub = {
    (no1: Int, no2: Int) -> Int in 
    return no1 - no2 
 }
 
 let digits = sub(10, 20)
 print(digits)

将速记参数名称声明为闭包

Swift自动为内联闭包提供简写参数名,可以使用$0、$1、$2等名称引用闭包参数的值。

var shorthand: (String, String) -> String
shorthand = { $1 }
print(shorthand("100", "200"))

这里,$0和$1引用闭包的第一个和第二个字符串参数。

Swift通过表示$0、$1、$2—$n方便用户将内联闭包表示为简写参数名。

在定义部分中,当我们在闭包表达式中表示简写参数名时,将省略闭包参数列表。将根据函数类型派生出简写参数名。由于简写参数是在表达式体中定义的,所以省略了’in’关键字。

闭包作为操作符函数

Swift提供了一种简单的方法来访问成员,只需提供像闭包一样的操作符函数。在前面的例子中,关键字“Bool”用于在字符串相等时返回“true”,否则返回“false”。

在闭包as -中的算子函数使表达式更简单

let numb = [98, -20, -30, 42, 18, 35]
var sortedNumbers = numb.sorted ({
   (left: Int, right: Int) -> Bool in
   return left < right
})

let asc = numb.sorted(<)
print(asc)

闭包作为代码片段

将函数的最后一个参数传递给闭包表达式,它用{}写在函数()的外面,当不能在一行中内联地编写函数时,就需要使用它。

reversed = sorted(names) { $0 > $1}

其中{$0 >
$1}表示为在外部声明的尾随闭包(名称)。

import Foundation
var letters = ["North", "East", "West", "South"]

let twoletters = letters.map({ 
   (state: String) -> String in
   return state.substringToIndex(advance(state.startIndex, 2)).uppercaseString
})

let stletters = letters.map() { 
   $0.substringToIndex(advance($0.startIndex, 2)).uppercaseString 
}
print(stletters)

捕获值和引用类型

在Swift中,捕获常量和变量值是在闭包的帮助下完成的,它进一步引用和修改闭包体中那些常量和变量的值,即使这些变量不再存在。

通过使用嵌套函数在其他函数体中写入函数来获取常量和变量值。

  • 嵌套函数捕捉-
  • 外部函数参数。

捕获外部函数中定义的常量和变量。

在Swift中,当一个常量或变量在一个函数中声明时,对该变量的引用也会由闭包自动创建。它还提供了一种方法,可以将两个以上的变量称为以下相同的闭包

let decrem = calcDecrement(forDecrement: 18)
decrem()

在这里,一个减量和一个减量变量都指向与闭包引用相同的内存块。

func calcDecrement(forDecrement total: Int) -> () -> Int {
    var overallDecrement = 100
    func decrementer() -> Int {
       overallDecrement -= total
       print(overallDecrement)
       return overallDecrement
    }
    return decrementer
 }
 
 let decrem = calcDecrement(forDecrement: 18)
 decrem()
 decrem()
 decrem()

当每一次外部函数calcDecrement称之为调用减量()函数衰减值18和返回结果的帮助下calcDecrement外功能,这里calcDecrement充当一个闭包。

尽管函数decrementer()没有任何参数,默认闭包“overallDecrement”和“total”是指变量通过捕获其现有值,指定变量的值的副本存储新decrementer()函数,Swift处理内存分配和释放内存空间管理功能,当变量是不使用的。

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?