swift学习笔记二

一、函数
1.swift中函数可以当作别的函数的参数,也可以从其他函数中返回
函数的定义可以写在其他函数的定义中,可以在嵌套函数范围内实现功能的封装

2.多重返回值函数
可以用元组类型作为一个复合值从函数中返回,元组的成员不需要再元组从函数中返回时命名

func minMax(array: [Int]) -> (min: Int, max: Int) {
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}
print(minMax(array: [1, 3, 3, 5, 6]))
//打印结果 (1, 6)

上面的函数返回的元组可以时(min: Int, max: Int)? 类型

4.默认参数
在函数体中通过给参数赋值来为任意一个参数定义默认值,当默认值被定义后,调用这个函数时可以忽略这个参数。

func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
    print(parameterWithDefault,parameterWithoutDefault)
}
someFunction(parameterWithoutDefault: 10)
someFunction(parameterWithoutDefault: 8, parameterWithDefault: 6)

5.可变参数
一个函数最多只能拥有一个可变参数,一个可变参数可以接受零个或多个值,函数调用时,你可以用可变参数来制定函数参数可以被传入不确定数量的输入值,通过在变量类型名后面加入(...)的方式来定义可变参数

func arithmeticMean(_ numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// 返回 3.0, 是这 5 个数的平均数。
arithmeticMean(3, 8.25, 18.75)
// 返回 10.0, 是这 3 个数的平均数。

6.输入输出参数(函数参数默认时常量,在函数体内不能改变他的值)
输入输出参数不能又默认值,而且可变参数不能用inout标记

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// 打印 "someInt is now 107, and anotherInt is now 3"

7.函数的类型
函数的类型是由函数的参数类型和返回类型组成
(Int, Int) -> Int

8.函数类型作为参数类型

func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _b: Int) {
        print(mathFunction(a, b))
}
printMathResult(addTwoInts, 4, 6)

9.函数类型作为返回类型

func stepForward(_ input: Int) -> Int {
    return input + 1
}
func stepBackward(_ input: Int) -> Int {
    return input - 1
}
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    return backward ? stepBackward : stepForward
}
var currentValue = 3
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero 现在指向 stepBackward() 函数。
print("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
    print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// 3...
// 2...
// 1...
// zero!

10.嵌套函数
可以把函数定义在别的函数体中,默认情况在外部是不能调用的,但是可以作为返回值返回

二、闭包
1.函数时特殊的闭包
全局函数是一个有名字但不会捕获任何值的函数
嵌套函数是有名字并可以捕获其封闭函数域内值的闭包

swift的闭包表达式拥有简洁的风格,并鼓励在场景中进行语法优化:
利用上下文推断参数和返回值类型
隐式表达单表达式闭包,即但表达式闭包可以隐藏return关键字
参数名称缩写
尾随闭包语法

2.闭包表达式语法

{ (parameters) -> returnType in
        statements
}

闭包的参数可以是 in-out参数,但不能设定默认值。也可以使用具名的可变参数,元组也可以作为参数和返回值

3.尾随闭包
如果你需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性。尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。在使用尾随闭包的时候,你不用写出他的参数标签

func someFunctionThatTakesAClosure(closure: () -> Void) {
    // 函数体部分
}

// 以下是不使用尾随闭包进行函数调用
someFunctionThatTakesAClosure(closure: {
    // 闭包主体部分
})

// 以下是使用尾随闭包进行函数调用
someFunctionThatTakesAClosure() {
    // 闭包主体部分
}

如果闭包表达式是函数或方法的唯一参数,甚至可以把函数后面的()省略

 someFunctionThatTakesAClosure{
      // 闭包主体部分
}

4.值捕获
闭包可以在其定义的上下文中捕获常量或者变量,即使这些常量或者变量的原作用域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。

5.闭包是引用类型
函数和闭包都是引用类型

6.逃逸闭包
当一个闭包作为一个参数传到一个函数中,但是这个闭包在函数返回之后才能执行,我们称该闭包从函数中逃逸,定义此类型的闭包的时候,在闭包前面添加关键字@escaping,用来指明这个表是允许逃逸出这个函数的。

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

someFunctionWithEscapingClosure(_:)函数接受一个闭包作为参数,该闭包被添加到函数外定义的数组中,如果不添加@escaping 编译就会报错

将一个闭包标记为@escaping 意味着必须在闭包中显示的引用self

func someFunctionWithNonescapingClosure(closure: () -> Void) {
    closure()
}

class SomeClass {
    var x = 10
    func doSomething() {
        someFunctionWithEscapingClosure { self.x = 100 }
        someFunctionWithNonescapingClosure { x = 200 }
    }
}

let instance = SomeClass()
instance.doSomething()
print(instance.x)
// 打印出 "200"

completionHandlers.first?()
print(instance.x)
// 打印出 "100"

7.自动闭包
自动闭包能让你延迟求值,因为知道你调用这个闭包,代码段才会执行

var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
print(customersInLine.count)
// 打印出 "5"

let customerProvider = { customersInLine.remove(at: 0) }
print(customersInLine.count)
// 打印出 "5"

print("Now serving \(customerProvider())!")
// Prints "Now serving Chris!"
print(customersInLine.count)
// 打印出 "4"

customerProvider的类型不是String 而是一个没有参数返回值为String的函数

将闭包作为参数传递给函数

// customersInLine is ["Alex", "Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: () -> String) {
    print("Now serving \(customerProvider())!")
}
serve(customer: { customersInLine.remove(at: 0) } )
// 打印出 "Now serving Alex!"

上面的 serve(customer:)
函数接受一个返回顾客名字的显式的闭包。下面这个版本的 serve(customer:)完成了相同的操作,不过它并没有接受一个显式的闭包,而是通过将参数标记为 @autoclosure来接收一个自动闭包。现在你可以将该函数当作接受 String 类型参数(而非闭包)的函数来调用。customerProvider参数将自动转化为一个闭包,因为该参数被标记了 @autoclosure特性。

// customersInLine is ["Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: @autoclosure () -> String) {
    print("Now serving \(customerProvider())!")
}
serve(customer: customersInLine.remove(at: 0))
// 打印 "Now serving Ewa!"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容