swift中嵌套函数与闭包的使用和区别

闭包是现代编程语言争相引入的一种语法,如果说函数是命名,方便复用的代码块,那么闭包则是功能更灵活的代码块,它可以在程序中被传递和调用,swift的闭包类似于object-c的代码块和java\c#\lambda表达式。

从另外一个角度来看,函数也可当做是闭包处理。

  1. 全局函数一个名称、但不会捕获任何值的闭包。
  2. 嵌套函数是一个名字、可以捕获封闭函数体的值的闭包
  3. 闭包表达式则是一个简洁的、可以捕获封闭函数体的值的匿名闭包。
嵌套函数使用前面文章已经举例
func getMathFunc(#type:String) ->(Int)->Int{
    func square(val:Int) ->Int{
        return val*val;
    }
    
    func cube(val:Int)->Int{
        return val*val*val;
    }
    
    func factorial(val:Int) ->Int{
        var result = 1;
        for index in 2...val{
            result *= index
        }
        return result
    }
    
    switch(type){
        
        case "square":
            return square;
        case "cube":
            return cube;
        default:
            return factorial;
    }
    
    
}

由于嵌套函数的作用域默认仅留在函数之内,因此这3个嵌套函数的函数名的作用太有限了-仅仅就是在程序的switch表达式中作为返回值使用,一旦离开了getMathFunc()函数体,三个嵌套函数的函数名就失去了意义。既然嵌套函数的函数名没有太大的意义,那么久考虑使用闭包表达式来简化嵌套函数的写法。

闭包代替嵌套函数的写法
func getMathFunc(#type:String) ->(Int)->Int{
    
    switch(type){
        case "square":
            return { var in val*val } //这个闭包可以上下文类型 是一种简写 或者 return { (var:Int) in Int return val*val }还可以省略形参名:return {$0*$0}
        case "cube":
            return {var in val*val*val}
        default:
            return {(var:Int)->Int in
                var result = 1
                for index in 2...val{
                    result *= index
                }
                return result
            }
        
    }
    
}
var mathFunc = getMathFunc(type:"square");
println(mathFunc(5) ) //25  得到square函数
mathFunc = getMathFunc(type:"cube");
println(mathFunc(5) ) //125 得到cube函数
mathFunc = getMathFunc(type:"factorial");
println(mathFunc(5) ) //120 得到factorial 函数

从调用的方式来看几乎和嵌套函数一样。

定义闭包和嵌套函数存在以下区别:

  1. 定义闭包无需func关键字,无须指定函数名
  2. 定义闭包需要额外的 in 关键字
  3. 定义闭包的第一个花括号要移动到形参列表的圆括号之前。