前面我们基本上了解了Swift的闭包简介,现在让我们来继续讲解闭包的其他内容:

1.Trailing闭包

在前面我们知道了简单的闭包是怎么样运用的,但在实际开发中,我们不可能只使用简单的闭包,所以这时候就出现了第二种闭包的写法,那就是Trailing闭包,让我们来看看例子:

let digitNames = [
    0: "Zero",1: "One",2: "Two",3: "Three",4: "Four",5: "Five",6: "Six",7: "Seven",8: "Eight",9: "Nine"
]

let numbers = [16,58,510]

let strings = numbers.map {
    (var number) -> String in

    var output = ""

    while number > 0 {
        output = digitNames[number % 10]! + output
        number /= 10
    }
    return output
}

println(strings)
// 打印出来的结果: [Onesix,FiveEight,FiveOneZero]

PS:
1.在这个例子中,strings 常量被推断为字符串类型数组,即 [String],map 在数组中为每一个元素调用了闭包表达式,您不需要指定闭包的输入参数 number 的类型,因为可以通过要映射的数组类型进行推断,闭包表达式在每次被调用的时候创建了一个字符串并返回。其使用求余运算符 (number %10) 计算最后一位数字并利用 digitNames 字典获取所映射的字符串.

2.字典 digitNames 下标后跟着一个叹号 (!),因为字典下标返回一个可选值 (optional value),表明即使该 key 不存在也不会查找失败,在上例中,它保证了 number % 10 可以总是作为一个 digitNames 字典的有效下标 key,因此叹号可以用于强展开 (force-unwrap) 存储在可选下标项中的 String 类型值.

2.捕获

在我们使用闭包的时候,其实我们还可以捕获我们自己定义的常量或者变量,即使里面的常量和变量的作用域不存在,闭包仍然可以在闭包函数体内引用或者修改,Swift 最简单的闭包形式是嵌套函数,也就是定义在其他函数体内的函数,嵌套函数可以捕 获其外部函数所有的参数以及定义的常量和变量,让我们一起来看看:

func makeIncrementor(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0

    func incrementor() -> Int {

        runningTotal += amount

        return runningTotal
    }
    return incrementor
}

let incrementBySeven = makeIncrementor(forIncrement: 7)
let a = incrementBySeven()
println(a)
// 打印出来的结果: 7

PS:
1.makeIncrementor 返回类型为 () -> Int,这意味着其返回的是一个函数,而不是一个简单类型值,该函数在每次调用时不接受参数只返回一个 Int 类型的值,关于函数返回其他函 数的内容,请查看 Function Types as Return Types.

2.makeIncrementor 函数定义了一个整型变量 runningTotal (初始为 0) 用来存储当前增加总数,该值通过 incrementor 返回.

3.makeIncrementor 有一个 Int 类型的参数,其外部命名为 forIncrement,内部命名为 amount,表示每次 incrementor 被调用时 runningTotal 将要增加的量.

4.incrementor 函数用来执行实际的增加操作,该函数简单地使 runningTotal 增加 amount,并将其返回.

5.Swift 会决定捕获引用还是拷贝值,您不需要标注 amount 或者 runningTotal 来声明在嵌入的 incrementor 函数中的使用方式,Swift 同时也处理 runingTotal 变量的内存管理操作,如果不再被 incrementor 函数使用,则会被清除.

还有另外一个例子也很好玩,比如:

let incrementBySeven = makeIncrementor(forIncrement: 7)
let a = incrementBySeven()
let b = incrementBySeven()
let c = incrementBySeven()
println("\(a),\(b),\(c)")
// 打印出来的结果: 7,14,21

上面已经很好的解释了,这里我就不多做解释了,还有一个注意点,21 let incrementByTen = makeIncrementor(forIncrement: 10) let A = incrementByTen() let B = incrementByTen() let C = incrementByTen() println("\(A),\(B),\(C)") // 打印出来的结果: 10,20,30

虽然这两个常量调用的是同一个闭包,但是它们之间所捕获的内容并没有关联,这个需要注意.

3.闭包是引用类型


上面的例子中,incrementBySeven 和 incrementByTen 是常量,但是这些常量指向的闭包仍然可以增加其捕获的变量值. 这是因为函数和闭包都是引用类型.

无论您将函数/闭包赋值给一个常量还是变量,您实际上都是将常量/变量的值设置为对应函数/闭包的引用,上面的例子中,incrementByTen 指向闭包的引用是一个常量,而并非闭包内容本身,比如:

let alsoIncrementByTen = incrementByTen()
println(alsoIncrementByTen)
// 打印出来的结果: 40

好了,这次我们就讲到这里,下次我们继续~

Swift基础语法: 23 - Swift的Trailing闭包, 捕获, 闭包是引用类型的更多相关文章

  1. ios – 声明NSDictionary并在Swift中添加键值对?

    我一直在尝试使用类类型键和值来声明一个NSDictionary,如下所示:这里,“Category”和“SubCategory”是全局类.我知道我不能将类类型用于关键字段.但是,无论如何,我应该做到这一点.有没有办法做到这一点?如何声明专门的NSDictionary或类似的东西来做到这一点?

  2. ios – Swift相当于`[NSDictionary initWithObjects:forKeys:]`

    Swift的原生字典是否与[NSDictionaryinitWithObjects:forKeys:]相当?假设我有两个带键和值的数组,并希望将它们放在字典中.在Objective-C中,我这样做:当然我可以通过两个数组迭代一个计数器,使用vardict:[String:Int]并逐步添加东西.但这似乎不是一个好的解决方案.使用zip和enumerate可能是同时迭代两者的更好方法.然而,这种方法

  3. ios – Swift中的UIView动画不起作用,错误的参数错误

    我正在尝试制作动画并使用下面的代码.我得到“无法使用类型’的参数列表调用’animateWithDuration'(FloatLiteralConvertible,延迟:FloatLiteralConvertible,选项:UIViewAnimationoptions,动画:()–>()–>$T4,完成:(Bool)–>(Bool)–>$T5)’“错误.这意味着我使用了错误的参数.我错了.请

  4. ios – 在Swift中获取Cocoa Touch Framework项目版本字符串

    有谁知道这是否是我的项目设置中的缺陷,Xcode中的一个错误,或者是否有一种方法可以将Swift中的框架版本作为String或数组获取,这样我可以提供比major.minor更精细的版本控制?

  5. ios – 搜索数组swift中的对象

    我正在尝试使用UISearchController创建搜索功能.但是,我似乎无法使其与我的团队对象一起工作.我首先创建了一个包含id,name和shortname的TeamObject.然后我从一个url中检索teamData,并将TeamObjects添加到一个填充到tableView中的数组中.这个tableView包含一个searchController,它假设过滤数据,但没有任何反应.阵列

  6. ios – Swift可选项:语言问题,还是做错了什么?

    应该有可选的类型;type是但是,如果我这样做,它的工作原理:它似乎是基本的替代,但我可能会遗漏一些语言的细微差别.谁能对此有所了解?之后就像暧昧一样,更多,这是我的解决方案:这适用于所有非对象Swift对象,包括Swift字符串,数字等.感谢Viktor提醒我String不是Swift中的对象.如果您知道值的类型,您可以替换任何?使用适当的可选类型,如String?

  7. ios – 使用捕获列表中的无主内容导致崩溃,即使块本身也不会执行

    欣赏有关如何调试此内容的任何提示或有关导致崩溃的原因的解释……

  8. ios – Swift – 使用字典数组从字典访问数据时出错

    我有一个非常简单的例子,说明我想做什么基本上,我有一个字典,其值包含[String:String]字典数组.我把数据填入其中,但当我去访问数据时,我收到此错误:Cannotsubscriptavalueoftype‘[([String:String])]?’withanindexoftype‘Int’请让我知道我做错了什么.解决方法您的常量数组是可选的.订阅字典总是返回一个可选项.你必须打开它.更

  9. ios – 在Swift中使用“Map”创建两个数组的超集

    假设我有两个数组:我想组合两个数组,以便我得到一个输出我该怎么做呢?

  10. 模糊地使用’下标’ – ios 9 Swift 2.0

    我在xcode7.0上使用Swift2.0编写iosapp.在更新到最新版本的xCode7.1之前,完全相同的代码完全正常更新后,我收到此错误:Ambiguoususeof‘subscript’在这些方面:这是全班:Theoriginallibrary解决方法编译器不知道self.itemAttributes[indexPath.section]返回的内容,因为它定义为NSMutableArray

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部