Swift:函数与闭包(block)

Functions and Closures

github:Swift基础实例
github:SwiftBasicTableView

函数
  • 函数声明
    func 声明一个函数,通过函数名来调用函数,函数如果有参数,在圆括号 () 中需要跟上相应参数。用符号 -> 把函数的参数和函数的返回值类型隔开。
var nameAndDay = ""
func greet(name: String, day: String, number: Int) ->String {
    return "Hello \(name), today is \(day), \(number)."
}
nameAndDay = greet("Swift", day: "Sunday", number: 1)
print(nameAndDay)
  • 输出 Hello Swift, today is Sunday, 1.
  1. 函数返回多个值
    从函数返回多个值时,可以使用元组 tuple ,通过 名字 或 索引来访问 tuple 中的值:
func calculate(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
    var min = scores[0]
    var max = scores[0]
    var sum = 0
    for score in scores {
        if score > max {
            max = score
        }
        else if score < min {
            min = score
        }
        sum += score
    }
    return (min,max,sum)
}
let statistics = calculate([5, 10, 39, 5])
print(statistics.sum)
print(statistics.1)
  1. 参数数量可变的函数
func sumOf(numbers:Int...) ->Int {
    var sum = 0
    // numbers.count
    for number in numbers {
        sum += number
    }
    return sum
}
print(sumOf())
print(sumOf(1,3,4,5))
  • 上面代码中,一系列的参数放在了一个数组 numbers
  1. 函数嵌套
    嵌套函数中,内层函数可以使用外层函数中的变量。一个函数中的代码如果太长,或者比较复杂,那么可以使用嵌套函数来组织组织这些代码:
func returnFifteen() ->Int {
    var y = 10
    func add() {
        y += 5
    }
    add()
    return y
}
print(returnFifteen())
  1. 返回函数
    Swift 的函数是第一类类型first-class type,这意味着一个函数可以把其他函数作为它的返回值:
func makeIncrementer() ->((Int)->Int) {
    func addOne(number:Int) ->Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
print(increment(7))
  • 在函数 makeIncrementer 中,构造了另外一个函数 addOne 并将其返回,返回函数名就可以(猜测,可能返回的是函数指针)
  1. 函数作为参数
    一个函数可以作为另外一个函数的参数,传递进去:
func lessThanTen(number:Int) ->Bool {
    return number < 10
}
func hasAnyMatches(list:[Int], condition:(Int) ->Bool) ->Bool {
    
    for item in list {
        if condition(item) {
            return true
        }
    }
    return false
}
var numbers = [20,13,4,9]
hasAnyMatches(numbers, condition: lessThanTen)
  • 传递函数时,也是只传递名称就可以
闭包(block)

闭包格式

{ (参数) -> 返回值类型 in
    statements
}```
- 有名称的闭包
函数是特殊的闭包:代码块可以稍后被调用。上面的嵌套函数,就属于是有名字的闭包,无名的闭包(`匿名闭包`)是不写名字(比如`函数名`),然后把代码放在大括号`{}`中。再看下面的栗子:假设我们要写两个函数,一个计算两个数的平方的平均值,一个计算两个数的立方的平均值,一般做法是:

func square(a:Float) ->Float {
return aa
}
func cube(a:Float) ->Float {
return a
a*a
}
func averageSumOfSquare(a:Float, b:Float) ->Float {
return (square(a) + square(b))/2.0
}
func averageSumOfCube(a:Float, b:Float) ->Float {
return (cube(a) + cube(b)) / 2.0
}
averageSumOfSquare(1.0, b: 3.0)
averageSumOfCube(2.0, b: 3.0)

上面函数 `averageSumOfSquare` 和 `averageSumOfCube` 唯一不同之处就是分别调用了平方函数和立方函数。如果我们可以定义这样一个函数,这个函数以两个数和一个使用这两个数的函数作为参数,来计算平均值而不是重复调用将会非常好,我们可以使用闭包作为函数参数:

func averageOfSum(a:Float, b:Float, f:(Float ->Float)) ->Float {
return (f(a) + f(b))/2.0
}
averageOfSum(2.0, b: 3.0, f: square)
averageOfSum(3.0, b: 3.0, f: cube)

   - `square`和`cube`可以被看做有名称的闭包

2. 无名称闭包
下面说一下无名内联闭包,代码也是写在大括号 `{}` 中,代码用 `in` 将参数和返回类型与实现(`body`)隔开:

// 注意格式,每一行换行的地方
individualScores.map({
(number:Int) ->Int in
let result = number+3
return result
})


3. 闭包简写
如果闭包的类型是已知的,比如 `delegate`,那么可以删掉闭包的`参数类型`或`返回类型`,或者两者都删掉。单语句闭包隐式返回这条语句的执行结果.

individualScores.map({
number in number+3})
print(individualScores)
let mappedScores = individualScores.map({
number in number+3})

   - 数组 `individualScores` 中的值没有变化,而是调用 `.map` 之后会返回一个新的数组,新数组`mappedScores`中的值会每个都加3

   我们还可以忽略参数名,使用默认参数名`$0`,如果有多个参数,使用 `$n` 作为第 `n-1` 个参数:

individualScores.map({
$0+3})

如果某一个函数的最后一个参数是闭包,那么这个闭包可以直接出现在圆括号`()`之后,例如下面的升序排序:

let sortedNumbers = individualScores.sort(){
$0 < $1
}
print(sortedNumbers)

如果某一个函数唯一的参数是闭包,那么可以把圆括号`()`省略掉:

let sortedNumbers = individualScores.sort {
$0 < $1
}
print(sortedNumbers)


4. 总结
>闭包是函数的一种,但闭包的真正意义是:把参数传递进一个块(这个块是用来实现闭包的),然后对参数就行修改,修改过之后,再使用。总结为一句话,传递参数-->修改-->使用
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容