加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift - closure

发布时间:2020-12-14 06:49:46 所属栏目:百科 来源:网络整理
导读:closure closure是一种类似于函数的类型,也是first class type的一种。 closure是引用类型,有自己的指令和空间。 closure可以看作是一种轻量级的函数,它的一般格式如下: // 声明 let 名字 = { (参数) - 返回值 in closure的内容} // 调用 let 返回值 =

closure

closure是一种类似于函数的类型,也是first class type的一种。
closure是引用类型,有自己的指令和空间。
closure可以看作是一种轻量级的函数,它的一般格式如下:

//声明
let 名字 = {(参数) -> 返回值 in
    closure的内容
}
//调用
let 返回值 = 名(参数)

//声明与调用合并使用
let 返回值 = {(参数) -> 返回值 in closure的内容}(实参)

closure参数的语法

有外参名

这种情况下closure与function的参数用法是一样的

func area(length l : Int,width w : Int) -> Int {
    return l * w
}
let a = area(length : 2,width : 3)

let area{ (length l : Int,width w : Int) -> Int in
    return l * w
}
let a = area(length : 2,width : 3)
无外参名

closure不需要通过_来隐藏外参名

func area(length : Int,_width : Int) -> Int {
    return length * width
}
let a = area(2,3)

let area{ (length : Int,width : Int) -> Int in
    return length * width
}
let a = area(2,3)

看上去closure只是参数和返回值放在函数体里面的function?
NO!
swift的类型推导功能在closure上发挥得淋漓尽致。使得closure的语法更简洁易读。

类型推导

Void

假设c1是一个没有入参和返回值的closure,那么它应该这么写。

let c1 = {(_ : Void) -> Void in
    ...
}

事实上它可以写得更简洁:
(1)当closure的参数是Void类型时,可以省略不写

let c1 = {() -> Void in
    ...
}

(2)当closure的返回值是Void类型时,也可以省略不写

let c1 = { () in
    ...
}

(3)当closure的参数和返回值都是Void类型时,整体可以直接进入closure体

let c1 = { ... }
赋值

赋值表示式的一般格式为expression = value
在closure中,只要其中一方指明了类型,另一方的类型就可以自动推导出来

let tm = { () -> String in
    ...
    return str
}

自动推导出tm的格式为() -> String
或者这样写:

let tm : () -> String = {
    ...
    return str
}

这种情况下,就不需要写明closure表达式的参数和返回值了。

作为参数

假设有这样一个需求:

func bySquare(edge : Int) -> Int {
    return edge * edge
}
func area(length : Int,calculate : Int -> Int) -> Int {
    return calculate(length)
}
let a = area(5,calculate : bySquare)

这里使用了函数bySquare作为参数来决定使用什么方式计划面积。如果要使用closure bySquare作为参数,则应该这么写:

func area(length : Int,bySquare : {(edge : Int) -> Int in
                       return edge * edge
                     }
         )

(1)closure的内容只有一行,因此return可以去掉

func area(length : Int,bySquare : {(edge : Int) -> Int in
                       edge * edge
                     }
         )

(2)参数类型和返回值可以根据closure内容推导出来,所以可以省去。用’$’+’数字’代表使用的是第几个参数。

func area(length : Int,bySquare : { $0 * $0 }
         )

(3)因为closure是最后一个参数,因此可以使用trailing closure语法

func area(length : Int) { $0 * $0 } )
语句表达式
let area = {(r : Double) -> Double in
                return 3.14 * r * r
           }

可简化为:

let area = { 3.14 $0 * $0 }
语境

例子1:

let array = [1,2,3,4,5]
array.map( { (u:Int) -> Bool in return (u%2) == 0 } )

可简化为:

let array = [1,5]
array.map() { ($0%2) == 0 }

例子2:如果closure内容只是一个函数调用,可以进一步简化

let yy = radians.map() { sin($0) }
let yy = radians.map( sin )

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读