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

在Swift中函数的表现形式如下:

1. func 函数名(参数名1:参数类型,参数名2,参数类型)->返回值类型 {函数的实现部分}

func sayHello()->Void {

print("hello world")

}

//有参数,有返回值,

func sayHello2(personName:String)->String {

let msg:String = "hello" + personName + "!"

return msg

}

sayHello2("a gan zuo")

// 有参数 无返回值

func showPersonInfo(personName:String,personAge:Int) ->Void {

print("\(personName)今年\(personAge)岁")

}

showPersonInfo("ZhangShan", personAge: 20)

//统计一段字符中制定字符的个数

let String = " I like you,I miss you,I love you,I hate you ,I wed you"

func  count(str:String) -> (me:Int,you :Int other:Int) {

var m = 0,y = 0, o = 0

for char in str.characters {

switch char {

case "I":

m++

case "u":

y++

default:

o++

}

}

return (m,y,o)

}

let showCharacterCount = count(String)

showCharacterCount.0

showCharacterCount.me

2. 函数参数的内部名和外部名之分, 其本质作用就是为了再调用函数时候能看到这个参数标示的是什么值,例如 是年龄的值,还是是名字的值

func fa1(innerName: Int) {  innerName为函数的内部名,第一个参数如果前面只有一个标示类似于这样就叫做内部名 }

函数的外部名,只能在函数外部使用,函数的内部名只能在函数的内部使用,在内部名前面加上一个空格和一个字符串标识就成了外部名

func fa(exteraName innerName:LocalName:Int) {

print("inner name:\(innerName)")  //此处如果换成外部名 exteraName 则程序会报错

}

fa(externaName:123)  //  外部名externaName只在外部做属性内容标示时使用

函数的从  第二个参数开始  及以后的参数默认即是内部名,又是外部名

func show(name:String, age:Int) {

//第一个name为内部名, 第二个age为内部或者外部名

print("\(name)的年龄是\(age)")

}

show("zhangshan", age: 31)

/**如果不希望使用默认的外部名,可以自己起外部名,在内部名的前面起一个名字空格隔开就是外部名*/

func pointWithX(x:Int ,AndY y:Int) {

print("point(\(x),\(y))")

}

pointWithX(3, AndY: 2)  //此处在默认的第二个参数前加上了 AndY空格标示更改了原来的外部名 y,而第一个参数默认是内部名,所以前面没有标示。

/**如果不希望显示外部名,则在外部名前面挤上 万能数字 _  下划线 */

func point(x:Int, _ y:Int) {   }

point(100,200)

3. 函数的默认值,一个函数的参数可以设一个默认值,如果这个参数没有传入值,则使用默认值,如果传入了就使用新的值。

func printArray(array:[Int] ,separate:String = ",",flag:Bool) {

if flag {  print "["}

for var  i = 0;i <array.count - 1;i++ {  print("\(array[i]\(separate))")}

if flag{print("]")}

}

var array = [9,5,2,7]

printArray(array,flag:ture)    //使用默认值

printArray(array,separate:"_",flag:ture)  //不使用默认值

/**函数的可变长参数,使用 类型名+ ...  表示有一堆这种类型的参数*/

fun getAvg(numbers:Double...) ->Double {

var total = 0.0

for num in numbers {

total += num

}  return total/Double(numbers.count)

}

getAvg(2.0,3.0,8.0)

/**C语言中的可变长参数

#include <stido.h>

#include <stdarg.h>

float sum(int n,...) {   //n代表元素的个数,....代表可变参数

va_list p;   //定义了一个指针p

va_start(p,n) //定义了指针开始的元素位置

for (int i = 0; i<n; i++) {

sum += va_arg(p,double)  //va_arg每调用一次p指针后移动一个元素

}

}

*/

4. 函数的重载的条件,

a.有两个及两个以上的方法,且方法名相同,参数个数,参数类型,参数顺序不同均满足

b.参数列表不同,参数外名不通,都可以形成重载关系

//有参与无参数

func test1(){}

func test1(a:Int){}

func test2(a:Int) {}

func test2(a:Int,b: Int) {}

func sayHello(a:String,b:Int) {}

fun  sayHello(b:String,a :Int) {}

fun  test3(a:Int,b :String) {}

fun  test3(a:Int,B b:String) {}

5. 函数的类型*******重点,当一个函数声明部分,去掉了函数名字,那么剩下的部分就函数了

var x:Int   //Int 类型变量

void test(){}    void()   //C函数类型  void(*pfun)()   //C函数指针类型

Int getMax(int x,int y)     //int (int x,int y)类型,int(*pfun)(int x,int y) //函数的指针类型

func sayHello() {   print("hello")}

//  ()->(Void):Swift中无参无返回值的类型,void可以省略,代表没有参数,与C语言中Void相似。

下面定义了一个(Int,Int)->Int 型的函数,能指向这一类型的函数,我们可以通过构造这种类型函数的不通逻辑,来实现加 减 乘 除

func  addTwoInts(a: Int,b :Int)->Int { return a + b}

func addTwoInts(a: Int,b: Int)->Int { return a - b}

//函数也可以作为一种变量来进行赋值,将一个函数赋值给另外一个变量,根据前面学到过的Swift自动推算类型,左边被赋值的变量也变成了和它具有一样功能的函数了

var function = subTwoInts   //函数指针赋值。

var function1:(Int,Int) ->Int = addTwoInts  //同前面所学的类型标注,函数名也可以拿来作为类型标注。

function2(100,200)  //无类型标注,我们看不到第二个参数的 外部参数名

function(100, b:200) //赋值时有使用函数类型标注,我们可以看到第二个参数的外部名

//定义一个函数,赋值sayHello要求带一个类型标注,带一个参数

func sayHello(content:String) { print("\(content)")}

var function3:(String) ->() = sayHello

function3("hello baby!")

/** 定义一个函数,赋值sayHello要求类型标注,不带参*/

func sayHello2() {

print("no arguments,no return values")

}

var function4:()->() = sayHello2

function4()

//下面主要进行无参无返回值的变换,根据标注类型的不同进行变换

var function5:()->(Void) = sayHello2

var fucntion6:(Void)->(Void) = sayHello2

var function7:Void ->Void = sayHello2

var function8 = sayHello2  //此步骤需要先知道sayHello2的函数类型,自动推导获得,相比OC最大的进步也就是自动推导了

function8()

//写一个整形参数,返回两个数的乘积

func mulTwoInts(a :Int,b :Int) ->Int {  return a * b }  //当代码中只有一行语句时,可以省略return关键字

// 写一个函数,传入一个函数类型参数。

func getResult(function:(Int,Int)->Int)->Int {  //在C中常是这样定义的int (*p)()(int,int)

let result = function(a,b)

return result

}

/**下面通过给getResult函数传入一个(Int,Int)->Int类型的函数 作为参数,内不调用该传入的函数,然后再传入 定义好的a,b变量*/

var a=100,b =99

func getResult(function:(Int,Int) ->Int) ->Int { let result = function(a,b)  return result}

getresult(addTwoInts)

getresult(sunTwoInts)

getresult(mulTwoINts)

getresult { (a,b) ->Int in return a* b}

/** 函数数组 数组中的每个元素都是函数,c语言中对应的叫函数数组*/

var nums:[Int] = [1,2,3,4,5,6] ;   nums[0]

var funs:[(Int,Int)->Int] = [addTwoInts,subTwoInts,mulTwoInts]

funs[0](100,200)

funs[1](100,200)

funs[2](100,200)

// 函数座位一个函数的返回值类型,此处定义了一个函数做为返回值。这个和OC中的Block做返回值还是有几分像

func test()->(Int,Int)->Int {

return addTowInts   //只需要返回类型的函数 返回就可以了,这里对应的返回值函数类型 (Int,Int)->Int

}

/** 嵌套函数,如果传真则是返回加法函数,如果为假则返回其它函数*/

func twoInts(isAddBool)-> (Int,Int)->Int  {

//此处我们除了可以使用已经定义好的 addTwoInts 和subTwoInts函数,还可以在此函数内部定义辅助函数,也可以作为私有函数,它的作用阈就限定在这个 {} 内

func addTwoInt2 (a :Int, b:Int)->Int ){  return a + b }

func subTwoInt2 (a: Int, b:Int)-> Int){  return a - b }

if isAdd {  return addTwoInt2} else { return subTwoInts}

}

twoInts(ture)(100,200)  //注意此处,实际是先调用TwoInts(ture) 此时返回一个 addTwoInt2函数

然后次函数传入(100,200)这两个参数相当于再调用addTwoInt2(100,200)  可得结果为300

6. 函数的闭包,Swift中重点之重点.

下面我们首先来了解一下它在其它语言中的表现形式:

Swift   ---- Closure 闭包

Ruby OC  -----Block  代码块

C++ -----Lambda  演算

javascript ------anonymous function 匿名函数

它的本质就是将一段代码封装起来,变成一个类似于变量的玩意;在Swift中如果一个 函数的参数 是 函数类型,那么可以将一个功能相同的代码(闭包)传给它。OC中的Block不能传函数类型,但可以传代码 。所以说闭包可以理解为函数,但是比函数的功能要多的多。

基本语法格式:

{ (参数列表)->返回值类型 in 执行代码语句}

而OC中Bloc的主要表现形式

^ 返回值类型(参数列表) {执行代码语句 }

//定义一个函数类型,或者是闭包类型,如下所示,只要函数类型与  闭包中 参数表->返回值类型 相同就可以警醒函数赋值。而 函数的实现体部分代码 即为 闭包内  in后面的代码

var sayClosure:(Int,Int)->Int;

sayClosure = {(x :Int,b: Int)->Int in return x + y }

sayClo(100,200)

/** OC中Block定义方式 定义上面的闭包函数

int (^sumBlock)(int,int);

sumBock = ^int(inta,int b){ return a + b; };

typedef double(^SumBlock)(int,int); 定义了一个SumBlock的类型

SumBlock s =^double(int i1,int i2) {  return i1 + i2; };

*/

7 . Swift中的冒泡排序,实现原理  挨个取出数组前面的数,然后将该数与它后面所有的数进行比较,根据大小调换数值。

func paopaoSort(inout data[Int],function:(Int,Int)->Int) {

for var i =0;i < data.count - 1;i++ {

for var j = i+1; j< data.count; j ++ {     // i+1 表示从 i后面的数开始逐个取出与i进行比较

if (function(data[i],data[j]))

swap(&data[i],&data[j])       }}}

let data:[Int] = [9,3,56,7,8]

func sortDes( a:Int, b:Int )-> Bool {  return  b - a  }

func sortAsc( a, b) -> Bool {  return a - b   }  //根据a,b传入值的类型可以省略 Int ,Int

paopaoSort(&data,function: sortDes)

paopaoSort(&data,function: sortAsc)

//其它奇葩的写法:

sortData(&data){$0 < $1}   // $0表示第一个参数 , $1表示第二个参数; 再运行的时候判断

data[i] < data[j ]

sortData(&data,function: >)    //把> 做为一个函数参数整体 ; 再调用的时候相当于讲function(data[i],data[j]) 替换成了  >

8. Swift中默认的函数相关用法

var names = ["aaa","ddd","fdsaf","fdsa"]

names.sort()  //会自动对数组names中的元素进行排序

name.sort{ (a,b) -> Bool in return a > b} //也可以通过此方式返回a与b的比较结果决定排序顺序。当sort函数或得此Bool值后,内部根据降序活着升序自动进行排序运算。

names.sort{  return $0 > $1 }  //具有相同的功效

var numbers:[Int] = [1,35,5643,653]

//map方法,把数组中的每个元素都取出来,放入闭包函数中执行,把所有执行的结果放入新的数组中

//下面这句话表示从通过numbers 中取出每个元素,然后进行相加,最后返回一个所有元素+20后的新的数组

var newNumber = numbers.map{ (number:Int) in return number + 20 }

也可以写成

var newNums2 = numbers.map({(x) -> Int in retunr x +10 })

当然还可以写成多种方法,自己慢慢摸索去,基本之遥不报错就Ok了

/**拖尾闭包(尾随闭包) 如果一个函数中最后的一个参数是闭包函数或闭包函数,可以将其写在()外面*/

如下定义的函数: 该函数中最后一个参数 function:(Int)->Int 闭包函数

func test(a:Int, b Int , function:(Int)->Int ) {  }

test(100,b:200) {(x) -> Int in return  x + 10 }

test(100,b:200, function:{(x)->Int in return x + 100})

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

  1. 4 .Swift函数|闭包

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

  2. Swift语法基础入门三(函数, 闭包)

    Swift语法基础入门三(函数, 闭包) 函数: 函数是用来完成特定任务的独立的代码块.你给一个函数起一个合适的名字,用来标识函数做什么,并且当函数需要执行的时候,这个名字会被用于“调用”函数 格式: ...

  3. Swift: 比较Swift中闭包传值、OC中的Block传值

    一.介绍 开发者对匿名函数应该很清楚,其实它就是一个没有名字的函数或者方法,给人直观的感觉就是只能看到参数和返回值.在iOS开发中中,它又有自己的称呼,在OC中叫Block代码块,在Swift中叫闭包 ...

  4. Swift:闭包

    一.闭包的介绍 闭包表达式(Closure Expressions) 尾随闭包(Trailing Closures) 值捕获(Capturing Values) 闭包是引用类型(Closures Ar ...

  5. Swift函数编程之Map、Filter、Reduce

    在Swift语言中使用Map.Filter.Reduce对Array.Dictionary等集合类型(collection type)进行操作可能对一部分人来说还不是那么的习惯.对于没有接触过函数式编 ...

  6. 如何在C语言中调用Swift函数

    在Apple官方的<Using Swift with Cocoa and Objectgive-C>一书中详细地介绍了如何在Objective-C中使用Swift的类以及如何在Swift中 ...

  7. Swift学习--闭包的简单使用(三)

    一.Swift中闭包的简单使用 override func viewDidLoad() { super.viewDidLoad() /** 闭包和OC中的Block非常相似 OC中的block类似于匿 ...

  8. iOS - Swift Closure 闭包

    1.Closure 闭包在 Swift 中非常有用.通俗的解释就是一个 Int 类型里存储着一个整数,一个 String 类型包含着一串字符,同样,闭包是一个包含着函数的类型.有了闭包,你就可以处理很 ...

  9. Swift使用闭包表达式

    Swift中的闭包表达式很灵活,其标准语法格式如下:{ (参数列表) ->返回值类型 in    语句组}其中,参数列表与函数中的参数列表形式一样,返回值类型类似于函数中的返回值类型,但不同的是 ...

随机推荐

  1. NOIP2005 过河

    过河 (river.pas/c/cpp) [问题描述] 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正 ...

  2. NOIP2013 货车运输

    3.货车运输 (truck.cpp/c/pas) [问题描述] A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货 ...

  3. Morris Traversal

    昨天临近要睡觉的时候做了一个leetcode题目,"Recover BST",算法很容易就想到了,直接找出两个异常点就好了,但是我写的算法是用栈实现的非递归遍历,空间复杂度是O(N ...

  4. Oracle-PLSQL Developer使用笔记

    1.新建菜单 command window ---->命令行,执行sql语句 sql window ---->执行sql语句,可导出CSV,TSV,HTML,XML等类型文件 report ...

  5. iOS开发之详解正则表达式

    本文由Charles翻自raywenderlich原文:NSRegularExpression Tutorial: Getting Started更新提示:本教程被James Frost更新到了iOS ...

  6. [转]jquery.vTicker(垂直滚动)

    转至:http://www.w3ci.com/plugin/660.html 简介 vTicker 是一款非常小巧的 jQuery 垂直滚动插件,压缩后只有 2KB.vTicker 支持自定义滚动时间 ...

  7. HDU2177:取(2堆)石子游戏(威佐夫博弈)

    Problem Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同 ...

  8. idea生成JAVADOC 报java.lang.IllegalArgumentException解决方案[终极]

    idea生成javadoc文档,总是会报  java.lang.IllegalArgumentException     at sun.net.www.ParseUtil.decode(ParseUt ...

  9. android studio 真机调试

    1.使用usb连接电脑,打开开发者选项,打开usb调试. 2.不能使用仅充电,修改为媒体设备(MTP) 3.如果无法连接可以使用豌豆荚或者金山手机助手连接. 4.运行android程序即可. 5.如果 ...

  10. ubuntu下查看文件md5

    终端输入md5sum --help: md5sum --help用法:md5sum [选项]... [文件]...显示或检查 MD5(128-bit) 校验和.若没有文件选项,或者文件处为" ...