Swift-闭包

作者: sipdar | 来源:发表于2014-06-12 11:00 被阅读4299次

    Swift 闭包

    函数 ()->()

    Swift 中的闭包和 Objective-C 中的 block 类似,闭包是功能性自包含模块,可以在代码中被传递和使用。 在 Swift 中 函数只是闭包的一种特殊形式。

    1.全局函数是一个有名字但不会捕获任何值的闭包
    2.内嵌函数是一个有名字可以捕获到所在的函数域内值的闭包
    3.闭包表达式是一个没有名字的可以捕获上下文中的变量或者常量的闭包

    定义函数

    我们在 Swift 中使用 func 关键字来定义函数,函数可以没有参数和返回值,也可以有一个或者多个参数和返回值。在Swift中多个参数的返回值叫做元组(tuples)

     func foo(firstname:String ,lastname:String)->(fullname:String){
          return("\(firstname) \(lastname)")
     }
    

    函数调用

     let fullname = foo("zhao”,”sunny”)
    

    函数类型

    每一个函数都有它的类型,函数的类型由函数本身的参数类型和返回值类型来决定的。

      func sum(x:Int,y:Int) -> (result:Int){return x + Y}
    

    上面这个函数的函数类型就是

      (Int,Int)->(Int)
    

    函数类型在构建函数的时候当成参数类型或者返回值类型来使用。

    返回函数类型

    func foo()->((String,String) -> String){
       func bar(firstname:String,lastname:String) ->(fullname:String){
        return("\(firstname) \(lastname)")
      }
      return bar
    }
    let namecombination = foo()
    namecombination("wang","er")
    

    可变参数函数

    可变参数函数是指函数可以接收不固定个参数。在参数类型后面添加 来标记这个参数为可变参数。我们可以在函数中像访问数组一样访问可变参数。

    func foo(names:String...) ->() {
      for name in names {
       println("\(name)")
      }
    }
    func foo("zhao","zhang","wang")
    

    In-out 参数函数

    传入函数的参数值只能在函数域内改变。参数传递是值传递,也就是说我们在函数内部修改了一个参数的值,在函数结束后,函数外部访问到的参数值还是传入函数之前的值,它并没有随着函数内的修改而改变。在Objective-C 我们通过指针来保存函数内修改过的值以供函数结束后外部访问。常见的例子就是 NSError 的使用。
    Swift 中我们也可以做类似的操作。我们需要inout 关键字来标记要修改的参数。

    func swapTwoInts(inout a: Int, inout b: Int) { 
        let temporaryA = a
         a = b 
            b = temporaryA
     }
     var someInt = 3 
     var anotherInt = 107 
     swapTwoInts(&someInt, &anotherInt)  
    

    闭包 { ()->() in }

    定义一个闭包

    闭包是一个使用花括号{} 包围起来,并且使用函数类型()->()来定义的代码模块。->符号分割了输入参数和返回值类型。在关键字 in 来区分闭包的头和闭包函数体。

     {(params) -> returnType in 
        statements
     }
    

    一个数组的map闭包的例子

    let names = ["zhao","wang","Li"]
    names.map({
      (name:String) -> String in 
       "\(name) has been map !"
    })
    

    已知参数类型的闭包

    map的闭包是作为函数参数传入的,所以 Swift 是可以做类型推断的,这样的话我们就不需要在闭包中在描述闭包的函数类型,也就是我们可以省略 (String) -> (String) 部分,来简写闭包表达式

    let names = ["zhao","wang","Li"]
    names.map({
      name in 
        "\(name) has been map !"
    }) 
    

    如果闭包有返回值我们也可以简写省略掉return

    例如

    let names = ["zhao","wang","Li"]
    let orderNames = sort(names,{s1,s2 in s1 > s2})
    

    闭包参数名简写

    Swift 为内联函数提供了参数名称简写功能,您可以直接通过 $0,$1,$2等名字来引用的闭包的参数的值。

    let names = ["zhao","wang","Li"]
    names.map({"\($0) has been map !"})
    sort(names,{$0 > $1})
    

    如果闭包是函数的最后一个参数,我们可以省略掉圆括号

    names.map{"\($0) has been map !"}
    sort(names){$0 > $1}
    

    对于排序函数 sort() 来说作为参数的闭包表达式只进行了两个值的比较,比较是通过操作符 >来进行的。在Swift中可以进行操作符重载,我们会发现在String 中定义了>的函数实现,也就是 > 本身就是一个函数 ,它接收两个String 类型的参数 并返回一个Bool类型的值。这和 Sort 函数的第二个参数的类型是一致的。所以,我们还可以进一步简写 Sort()

    sort(names,>)
    

    闭包跟函数是引用类型

    无论您将函数/闭包赋值给一个常量还是变量,您实际上都是将常量/变量的值设置为对应函数/闭包的引用。这也意味着如果您将闭包赋值给了两个不同的常量/变量,两个值都会指向同一个闭包.

    相关文章

      网友评论

      • 640aecced309:let names = ["zhao","wang","Li"]
        names.map({"\($0) has been map !"})
        sort(names,{$0 > $1})
        这段代码运行报错,“cannot invoke 'sort' with an argument list of type '([String],(_,_)->_) '”
      • 谢一面:闭包sort的例子会报错(swift文档上那个也会报错):
        '[String]' is not convertible to 'inout C'
        我的版本是 xcode6 beta5
        AliceJordan:let names = ["a","b","c"]
        let orderNames = names.sorted(){s1,s2 in s1>s2}
        print(orderNames)
        应该是这个样的吧

      本文标题:Swift-闭包

      本文链接:https://www.haomeiwen.com/subject/ijiktttx.html