函数

函数是一个完成独立任务的代码块,Swift中的函数不仅可以像C语言中的函数一样有函数的参数和返回值,而且还支持嵌套,并且有函数参数默认值、可变参数等。

 //定义一个函数,注意参数和返回值,如果没有返回值可以不写返回值或者写成Void、空元组()(注意Void的本质就是空元组)
func sum(num1:Int,num2:Int)->Int{
return num1 + num2
} sum(, )

可以看到Swift中的函数仅仅表示形式有所区别(定义类似于Javascript,但是js不用书写返回值),但是本质区别不大。不过Swift中对函数参数强调两个概念就是局部参数名(又叫“形式参数”)和外部参数名,这增大了开发者的开发体验。在上面的例子中强调了sum函数并没有传递任何参数名,因为num1、num2仅仅作为局部参数名在函数内部使用,但是如果给函数指定一个外部参数名在调用时就必须指定参数名。另外前面也提到关于Swift中的默认参数、可变长度的参数,包括一些高级语言中的输入输出参数,通过下面的例子可以全面的了解。

/**
/**
* 函数参数名分为局部参数名和外部参数名
*/
func split(string a:String,seperator b:Character)->[String]{
return split(a, maxSplit: Int.max, allowEmptySlices: false, isSeparator: {$==b})
} //由于给split函数设置了外部参数名string和seperator,所以执行的时候必须带上外部参数名,此处可以看到一个有意义的外部参数名大大节省开发者使用成本
split(string: "hello,world,!", seperator: ",") //结果:["hello", "world", "!"] //下面通过在局部参数名前加上#来简写外部参数名(此时局部参数名和外部参数名相同)
func split2(#string:String,#seperator:Character)->[String]{
return split(string, maxSplit: Int.max, allowEmptySlices: false, isSeparator: {$==seperator})
}
split2(string: "hello,world,!", seperator: ",") //上面的split函数的最后一个参数默认设置为",",注意如果使用默认参数那么此参数名将默认作为外部参数名(此时局部参数名和外部参数名相同)
func split3(#string:String,seperator:Character=",")->[String]{
return split(string, maxSplit: Int.max, allowEmptySlices: false, isSeparator: {$==seperator})
}
split3(string: "hello,world,!", seperator: ",") //结果:["hello", "world", "!"]
split3(string: "hello world !", seperator: " ") //结果:["hello", "world", "!"] //但是如果有默认值,又不想指定局部参数名可以使用“_”取消外部参数名
func split4(string:String,_ seperator:Character=",")->[String]{
return split(string, maxSplit: Int.max, allowEmptySlices: false, isSeparator: {$==seperator})
}
split4("hello,world,!", ",") //结果:["hello", "world", "!"] /**
* 可变参数,一个函数最多有一个可变参数并且作为最后一个参数
* 下面strings参数在内部是一个[String],对于外部是不定个数的String参数
*/
func joinStr(seperator:Character=",",strings:String...)->String{
var result:String=""
for var i=;i<strings.count;++i{
if i != {
result.append(seperator)
}
result+=strings[i]
}
return result
} joinStr(seperator:" ", "hello","world","!") //结果:"hello world !" /**
* 函数参数默认是常量,不能直接修改,通过声明var可以将其转化为变量(但是注意C语言参数默认是变量)
* 但是注意这个变量对于外部是无效的,函数执行完就消失了
*/
func sum2(var num1:Int,num2:Int)->Int{
num1 = num1 + num2
return num1
} sum2(, ) //结果:3 /**
* 输入输出参数
* 通过输入输出参数可以在函数内部修改函数外部的变量(注意调用时不能是常量或字面量)
* 注意:下面的swap仅仅为了演示,实际使用时请用Swift的全局函数swap
*/
func swap(inout a:Int ,inout b:Int){
a=a+b
b=a-b
a=a-b
} var a=,b=
swap(&a, &b) //调用时参数加上“&”符号
println("a=\(a),b=\(b)") //结果:"a=2,b=1"

和很多语言一样,Swift中的函数本身也可以看做一种类型,既可以作为参数又可以作为返回值。

 /**
* 函数类型
*/
var sum3=sum //自动推断sum3的类型:(Int,Int)->Int,注意不同的函数类型之间不能直接赋值
sum3(,) //结果:3 //函数作为返回值
func fn()->(Int,Int)->Int{
//下面的函数是一个嵌套函数,作用于是在fn函数内部
func minus(a:Int,b:Int)->Int{
return a-b
}
return minus;
}
var minus=fn() //函数作为参数
func caculate(num1:Int,num2:Int,fn:(Int,Int)->Int)->Int{
return fn(num1,num2)
} caculate(, , sum) //结果:3
caculate(,, minus) //结果:-1

闭包

Swift中的闭包其实就是一个函数代码块,类似于OC中的block。闭包的特点:可以捕获和储存上下文的常量或者变量的引用,即使这些常量或者变量在原作用域已经被销毁了,但在代码中仍然可以使用。事实上前面的全局函数和嵌套函数也是一种闭包,对于全局函数它不会捕获任何常量或者变量,而对于嵌套函数则可以捕获其所在函数的常量或者变量。通常我们说的闭包更多指的是闭包表达式,也就是没有函数名称的代码块,因此也叫做匿名闭包。

在Swift中闭包表达式的定义形式如下:

{(parameters)->returnType in

statements

}

下面通过一个例子看一下如何通过闭包表达式来简化一个函数类型的参数,在下面的例子中闭包的形式也是一而再再而三的被简化,充分说明了Swift语法的简洁性:

 func sum(num1:Int,num2:Int)->Int{
return num1 + num2
} func minus(num1:Int,num2:Int)->Int{
return num1 - num2
} func caculate(num1:Int,num2:Int,fn:(Int,Int)->Int)->Int{
return fn(num1,num2)
} var (a,b)=(,) caculate(a, b, sum) //结果:3
caculate(a, b, minus) //结果:-1 //利用闭包表达式简化闭包函数
caculate(a, b, {(num1:Int,num2:Int)->Int in
return num1 - num2
}) //结果:-1 //简化形式,根据上下文推断类型并且对于单表达式闭包(只有一个语句)可以隐藏return关键字
caculate(a, b, { num1,num2 in
num1 - num2
}) //结果:-1 //再次简化,使用参数名缩写,使用$0...$n代表第n个参数,并且此in关键字也省略了
caculate(a, b, {
$ - $
}) //结果:-1

考虑到闭包表达式的可读取性,Swift中如果一个函数的最后一个参数是一个闭包表达式,则可以将此参数写在函数括号之后,这种闭包称之为“尾数闭包”。

Swift:函数和闭包的更多相关文章

  1. 窥探Swift之函数与闭包的应用实例

    今天的博客算是比较基础的,还是那句话,基础这东西在什么时候都是最重要的.说到函数,只要是写过程序就肯定知道函数是怎么回事,今天就来讨论一下Swift中的函数的特性以及Swift中的闭包.今天的一些小实 ...

  2. swift基础:第二部分:函数和闭包

    今天本来想利用上午的时间本来打算将swift基础部分学习完的,不巧的是,后台来和我讨论用户评价的接口,讨论过后,商讨出一种可行的方案,十几分钟时间过去了,我拿到将接口介入到已经完成的页面中,完美,终于 ...

  3. swift 学习(二)基础知识 (函数,闭包,ARC,柯里化,反射)

    函数 func x(a:Int, b:Int)  {}   func x(a:Int, b:Int) -> Void {}  func x(a:Int, b:Int) ->(Int,Int ...

  4. 4 .Swift函数|闭包

    在编程中,我们常把能完成某一特定功能的一组代码,并且带有名字标记类型叫做函数,在C语言中,我们知道函数名就是一个指针,它指向了函数体内代码区的第一行代码的地址,在swift中也具有同样的功效. 在Sw ...

  5. Swift函数|闭包

    在编程中,我们常把能完成某一特定功能的一组代码,并且带有名字标记类型叫做函数,在C语言中,我们知道函数名就是一个指针,它指向了函数体内代码区的第一行代码的地址,在swift中也具有同样的功效. 在Sw ...

  6. 窥探 Swift 之 函数与闭包的应用实例

    今天的博客算是比较基础的,还是那句话,基础这东西在什么时候 都是最重要的.说到函数,只要是写过程序就肯定知道函数是怎么回事,今天就来讨论一下Swift中的函数的特性以及Swift中的闭包.今天的一些小 ...

  7. 苹果新的编程语言 Swift 语言进阶(六)--函数和闭包

    一 .函数 1.1. 函数的定义和调用 函数的定义以funckeyword作为前缀,接着是函数名字,接着跟着一个能够带有參数.也能够不带參数的圆括号.接着用-> 指示函数的返回类型. 函数运行体 ...

  8. Swift中文教程(四)--函数与闭包

    原文:Swift中文教程(四)--函数与闭包 Function 函数 Swift使用func关键字来声明变量,函数通过函数名加小括号内的参数列表来调用.使用->来区分参数名和返回值的类型: fu ...

  9. Swift 1.1语言第7章 函数和闭包

    Swift 1.1语言第7章  函数和闭包 在编程中,随着处理问题的越来越复杂.代码量飞速添加. 当中,大量的代码往往相互反复或者近似反复.假设不採有效方式加以解决.代码将非常难维护. 为了解决问题, ...

随机推荐

  1. 意外的节点类型 Element。只能在简单内容或空内容上调用 ReadElementString 方法

    问题出现的情景: 在调用携程团购接口时,需要把获取的xml字符串反序列化实体对象,出现了这个错误. 详情: 在对xml文档有这样一条语句“ <Description Category=" ...

  2. postgres 正则表达式

    PostgreSQL正则表达式 基础: Operator Description Example ~ Matches regular expression, case sensitive 'thoma ...

  3. CSS3发光字动画

    ;} img{ width:200px; height:200px; border:2px solid #000} .back h5 { font-size: 4em; color: #f2050b; ...

  4. NABCD模型(猫咪记单词)

    项目需求分析与建议-NABCD模型(猫咪记单词)   N (Need 需求) 对于现在的学生,尤其是大学生来说,学习英语是一件非常重要的事.我们有四级六级托福雅思等各种各样的英语方面的考试.而学习英语 ...

  5. 在Oracle中使用rank()over()排名的问题

    排序: ---rank()over(order by 列名 排序)的结果是不连续的,如果有4个人,其中有3个是并列第1名,那么最后的排序结果结果如:1 1 1 4 select scoreid, st ...

  6. JDE报表开发笔记(数据选择及继承)

    在Section的Event中, Do Custom Section("sectionxxx")自定义加载下一个Section Set Selection Append Flag( ...

  7. Java如何将控制台上的结果保存到文件

    无论是二进制数据还是字符数据(文本数据),都可以用文件输出流java.io.FileOutputStream,以字节流的方式保存到指定文件. package test; import java.io. ...

  8. priority_queue C++

    三种优先队列定义方法:T_T 内部原理以后补..... priority_queue<int> qi;//普通的优先级队列,按从大到小排序 struct Node { friend boo ...

  9. cf731E

    题意:一个游戏,由n张贴纸组成.贴纸排成一排,并且纸条上标有数字,玩家轮流揭下m张从左到右连续的纸条(m大等2),揭下后玩家得分累加这些纸条的sum,并且在剩下纸条最左边贴上新的纸条,数值为揭下纸条的 ...

  10. Resume Hook SSDT

    在HookSSDT中  通过在第4部通过索引将NtOpenProcess 换成 Base[索引] = FakeNtOpenProcess; so 在阻止时应该在ntoskrnl.exe 找到真正的Op ...