菜鸟教程Swift闭包教程
此篇同样是Swift语言学习系列的归纳笔记,内容源于菜鸟教程归纳

1.函数

用于完成特定任务的独立的代码块

  • 函数声明 : 告诉编译器函数的名字,返回类型及参数
  • 函数定义 : 提供了函数的实体

关键字func用于定义函数
每个函数都有一个函数名来描述它的功能,通过函数名以及对应类型的参数值来调用这个函数,函数的参数传递的顺序必须与参数列表相同
函数的实参传递的顺序必须与形参列表相同,->后定义函数的返回值类型

语法如下

func funcname(形参) -> returntype
{
   Statement1
   Statement2
   ……
   Statement N
   return parameters
}

范例:

func runoob(site: String) -> String {
    return (site)
}
print(runoob(site: "www.runoob.com"))

函数参数

函数可以接受一个或者多个参数也可以不带参数,这些参数被包含在函数的括号之中,用逗号分隔

不带参数的函数

func sitename() -> String {
    return "输出内容"
}

元组作为函数的返回值

Swift中的函数返回值可以是元组,也就是说可以返回多个值
范例(求出一个数组的最大值与最小值)

func minMax(array: [Int]) -> (min: Int, max: Int) {
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}

因此函数可以用一个元组变量接收
let bounds = minMax(array: [8, -6, 2, 109, 3, 71])
最后最大值与最小值可以用bounds.maxbounds.min来调用

如果你不确定返回的元组一定不为nil,那么你可以返回一个可选的元组类型,比如(Int, Int)?

没有返回值的函数

类似C语言的void类型函数,这里不多阐述

可变参数

除了固定参数数量的函数之外,函数接收的参数数还可以不定
可以通过在变量类型名后面加入(...)的方式来定义

func vari<N>(members: N...){
    for i in members {
        print(i)
    }
}

使用测试
三个整型:
vari(members: 4,3,5)
输出为

4
3
5

常量,变量和I/O参数

一般默认在函数中定义的参数都是常量参数,也就是说这个参数只可以查询使用,不能改变其值,如果想要声明一个变量参数(可以改变其值),需要在参数定义前添加inout关键字

func getName(_ name: inout String)

当传入的参数作为输入输出参数时,需要在参数名之前加&,表示该值可以被函数修改

范例:交换函数

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var x = 1
var y = 5
swapTwoInts(&x, &y)

该函数可以顺利的完成对x与y的值的交换

函数类型作为参数类型或作为返回类型

这部分也是看了一知半解,所以就直接上代码了以后在研究

func sum(a: Int, b: Int) -> Int {
    return a + b
}
var addition: (Int, Int) -> Int = sum
print("输出结果: \(addition(40, 89))")

func another(addition: (Int, Int) -> Int, a: Int, b: Int) {
    print("输出结果: \(addition(a, b))")
}
another(addition: sum, a: 10, b: 20)

2、闭包

闭包是自包含的功能代码块,可以在代码中使用后者用来作为参数传值

  • 全局函数与嵌套函数其实就是特殊的闭包

闭包的形式

形式解释
全局函数有名字但是不能捕获任何值
嵌套函数有名字,也能捕获封闭函数内的值
闭包表达式无名闭包使用轻量级语法,可以根据上下文环境捕获值

语法

{(parameters) -> return type in
   statements
}

实例

  1. 不带参数不返回参数的闭包
let studname = { print("Swift 闭包实例。") }
studname()
  1. 带两个参数并返回一个参数的闭包
let divide = {(val1: Int, val2: Int) -> Int in 
   return val1 / val2 
}
let result = divide(200, 20)
print (result)

闭包表达式

闭包表达式是一种利用简洁语法构造内联闭包的方式闭包表达式提供了一些语法优化
Swift标准库提供了名字为sorted(by:),会根据您提供的用于排序闭包函数将已知类型数组中的值进行排序(类似C标准库中的sort函数?)

排序完成后,该方法会返回一个与原数组大小相同,包含同类型元素并且元素已经正确排序的新数组,原数组不会被sorted方法修改

范例:字符串数组进行排序

let names = ["AT", "AE", "D", "S", "BE"]

// 使用普通函数(或内嵌函数)提供排序功能,闭包函数类型需为(String, String) -> Bool。
func backwards(s1: String, s2: String) -> Bool {
    return s1 > s2
}
var reversed = names.sorted(by: backwards)

print(reversed)

所得的reversed数组即为排序完成的数组

参数名称的缩写

Swift自动为内联函数提供了参数名称缩写功能,可以通过$0,$1,$2来顺序调用闭包的参数
$0表示闭包中第一个String类型的参数
$1表示闭包中第二个String类型的参数

因此上一个部分中的字符串数组排序程序也可以这样写

let names = ["AT", "AE", "D", "S", "BE"]

var reversed = names.sorted( by: { $0 > $1 } )
print(reversed)

运算符函数

所以折腾了半天告诉我还有更简单的方法?
方法如下

let names = ["AT", "AE", "D", "S", "BE"]

var reversed = names.sorted(by: >)
print(reversed)

捕获值

闭包可以在其定义的上下文中捕获常量或者变量
即使定义这些常量与变量的原域已经不存在闭包仍然可以在闭包函数体内引用与修改这些值

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议