Swift -3 函数和闭包

函数

Swift中函数是执行特定任务的代码自包含块。给定一个函数名称标识, 当执行其任务时就可以用这个标识来进行”调用”。
Swift的统一的功能语法足够灵活来表达任何东西,无论是甚至没有参数名称的简单的C风格的函数表达式,还是需要为每个本地参数和外部参数设置复杂名称的Objective-C语言风格的函数。参数提供默认值,以简化函数调用,并通过设置在输入输出参数,在函数执行完成时修改传递的变量。
Swift中的每个函数都有一个类型,包括函数的参数类型和返回类型。您可以方便的使用此类型像任何其他类型一样,这使得它很容易将函数作为参数传递给其他函数,甚至从函数中返回函数类型。函数也可以写在其他函数中来封装一个嵌套函数用以范围内有用的功能。

定义和调用函数

/*
    一.定义函数的语法格式
    func 函数名(形参列表) ->返回值类型{
    // 可执行语句组成的函数
}
*/
func sayHello(personName:String) ->String {

    return "Hello, " + personName + "!"
}
//print(sayHello("Devin"))

函数形参

func max(x: Int, y: Int) -> Int{

    return x > y ? x : y
}
//print(max(5, 3))

// 1.没有参数的函数
func sayHelloWorld() -> String{

    return "Hello World"
}
//print(sayHelloWorld())

// 2.外部参数名 局部参数名:形参类型
func area(width: Double, height: Double) -> Double{

    return width * height // width, height 不能在调用函数时使用,为局部参数
}
//print(area(4.5, height: 3.2))
func area1(宽 width: Double, 高 height: Double) -> Double{

    return width * height //width,height 不能在调用函数时使用,为局部函数
}
//print(area1(宽: 3.4, 高: 4.7))

// 3.外部参数和局部参数一样的话,需要在第一个参数前面加上同样的参数(swift2.0之后的写法)
func area2(width width: Double, height: Double) -> Double{

    return width * height //width,height 不能在调用函数时使用,为局部函数
}
//print(area2(width: 5, height: 2.4))

// 4.可变参数: 在参数类型后面加... 表示该参数可以接受多个参数值
func sum(numbers: Int...) -> Int{

    var total: Int = 0
    for num in numbers{

        total += num
    }
//    print(total)
    return total
}
sum(1, 3, 4, 5)

// 默认参数
func sayHi(msg: String, name: String = "Lily"){ // 这里就是默认参数

    print("\(name), \(msg)")
}
//sayHi("你好啊") // 如果没有传入参数,就会使用默认值
//sayHi("你好啊", name: "Tom")
// 可变参数放在最后面, 默认参数只能出现在次后面


// 6.常量形参和变量形参
func factorial(var number: Int) -> Int{

    var result: Int = 1
    while number > 1{

        result = result * number
        number--  // 这里如果定义的参数不带var的话就是默认常量,常量不能做--操作
    }
    return result
}
//print(factorial(3)) //3的阶乘

// 7.In-Our 形参
func swap(inout a: Int, inout b: Int){

    let tmp = a
    a = b
    b = tmp
}
var a: Int = 1
var b: Int = 3
swap(&a, b: &b)
//print("交换之后的结果为: a = \(a), b = \(b)")
/*
注意:
1.只能传入变量作为实参
2.输入输出参数不能带有默认值
3.如果你用关键字 inout 标记了一个参数,这个参数不能再用var或者let去标记
*/

返回值

// 没有指定返回类型的函数总返回 void,在Swift中,void可以理解为空元组
func sayHi1(){

//    print("Welcome")
}
sayHi1()

// 多个返回值
func area2(width: Double, height: Double) -> (Double, Double){

    let s = width * height
    let c = (width + height) * 2
    return(s, c)
}
//print(area2(3.1, height: 3.4))

函数类型

// 1.函数类型作为变量
func addTwoInts(a: Int, b: Int) -> Int{

    return a + b
}
func multiplyTwoInts(a: Int, b: Int) -> Int{

    return a * b
}
//var mathFunction:(Int, Int) -> Int = multiplyTwoInts
//print("result:\(mathFunction(2, 3))") // 函数变量赋值

// 2.函数类型作为参数类型
func printMathResult(mathFuction: (Int, Int) -> Int, a: Int, b: Int){

//    print("result:\(mathFuction(a, b))")
}
printMathResult(addTwoInts, a: 3, b: 5) // 这里函数作为参数传进去

// 3.函数类型作为返回值
func squre(num: Int) -> Int{

    return num * num
}
func cube(num: Int) -> Int{

    return num * num * num
}
func getMathFunc(type type: String) -> (Int) -> Int{

    switch(type){
    case "squre":
        return squre
    default:
        return cube
    }
}
var mathFunc = getMathFunc(type: "squr") // 根据传入的字符串判定返回的函数类型
//print(mathFunc(5))

函数重载

// 函数的重载指的是多个函数享有相同的名字都是有不同的参数或返回值类型不同,它们互相成为重载关系
func test1(){

//    print("无参数的test()函数")
}
func test1(mesg: String){

//    print("重载的test()函数\(mesg)")
}
func test1(msg: String) -> String{

//    print("重载的test()函数\(msg), 带返回值")
    return "test"
}
func test1(msg msg: String){

//    print("重载的test()函数,外部参数为\(msg)")
}
test1()
var result1: Void = test1("hello")
var result2: String = test1("welcome")
var result3: Void = test1(msg: "你好啊")

// 错误,仅有局部变量名不算重载
//func test1(message: String){
//    
//    print("重载的test()函数")
//}

闭包

闭包是功能性自包含模块,可以在代码中被传递和使用。Swift 中的闭包与 C 和 Objective-C中的 blocks 以及其他一些编程语言中的 lambdas 比较相似。
闭包可以 捕获 和存储其所在上下文中任意常量和变量的引用。这就是所谓的闭合并包裹着这些常量和变量,俗称闭包。Swift会为您管理在捕获过程中涉及到的内存操作。
在Swift函数中介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采取如下三种形式之一:
全局函数是一个有名字但不会捕获任何值的闭包
嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包
闭包表达式是一个利用轻量级语法所写的可以捕获其上下文中变量或常量值的没有名字的闭包

嵌套函数

func getMathFunc1(type type: String) -> (Int) -> Int{

    func squre1(num: Int) -> Int{

        return num * num
    }
    func cube1(num: Int) -> Int{

        return num * num * num
    }
    switch(type){
        case "squre1":
        return squre1
    default:
        return cube1
    }
}
var mathFunc1 = getMathFunc1(type: "squre1")
//print(mathFunc1(4))

闭包表达式

/*
    *{ (形参列表) -> 返回值类型 in
        可执行表达式
}
*/

func getMathFunc2(type type: String) -> (Int) -> Int{

    func squre1(num: Int) -> Int{

        return num * num
    }
    func cube1(num: Int) -> Int{

        return num * num * num
    }

    switch(type){
    case "squre1":

        return {(num: Int) -> Int in
            return num * num
        }
    default:

        return {(num: Int) -> Int in
            return num * num * num
        }

    }
}
// 返回(Int) -> Int 类型的函数
var mathFunc2 = getMathFunc2(type: "squre1")
//print(mathFunc2(3))

利用上下文推断类型

// var squre: (Int) -> Int = {(num) in return num * num}
// print(squre(3))
//var squre: (Int) -> Int = {num in return num * num} // 和上面一样的, 可以省略参数的括号
//print(squre(3))
// 省略形参名,通过$0, $1...来引用第一个,第二个参数
var squre1: (Int) -> Int = {$0 * $0}
//print(squre1(3))

var result: Int = {

    var result = 1
    for i in 1...$1{

        result *= $0
    }
    return result
}(4, 3)
print(result)
// 函数类型和闭包类型是一致的

尾随闭包

func someFunction(num: Int, fn: (Int) -> ()){

    // 执行代码
}
// someFunction(20, {})
// 使用尾随闭包调用函数的格式
// someFunction(20){}

捕获上下文中的变量或者常量

func makeArr(ele: String) -> () -> [String]{

    // 创建一个不包含任何元素的数组
    var arr: [String] = []
    func addElement() -> [String]{

        // 向arr数组中添加一个元素
        arr.append(ele)
        return arr
    }
    return addElement
}
// 闭包和函数都是引用类型,需要重点掌握闭包和函数

你可能感兴趣的:(iOS之Swift专题分享)