4 .Swift函数|闭包

在编程中,我们常把能完成某一特定功能的一组代码,并且带有名字标记类型叫做函数,在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})

时间: 2024-08-09 02:04:43

4 .Swift函数|闭包的相关文章

Swift函数闭包

一.闭包的概念 计算机语言要支持闭包的前提条件有2个: 1.支持函数类型,能够将函数作为参数或返回值传递: 2.支持函数嵌套 示例: func caculate(opr : String)->(Int,Int)->Int { var result:(Int,Int)->Int switch(opr){ case "+": result={(a:Int,b:Int)->Int in return a+b } default: result = {(a:Int,b:

Swift函数和闭包

函数 Swift 使用func关键字声明函数: 1 func greet (name: String, day: String) -> String { 2 return "Hello \(name), today is \(day)." 3 } 4 greet ("Bob", "Tuesday") 通过元组(Tuple)返回多个值: 1 func getGasPrices () -> (Double, Double, Double)

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

Swift语法基础入门三(函数, 闭包) 函数: 函数是用来完成特定任务的独立的代码块.你给一个函数起一个合适的名字,用来标识函数做什么,并且当函数需要执行的时候,这个名字会被用于“调用”函数 格式: func 函数名称(参数名:参数类型, 参数名:参数类型...) -> 函数返回值 { 函数实现部分 } 没有参数没有返回值 可以写为 ->Void 可以写为 ->() 可以省略 Void.它其实是一个空的元组(tuple),没有任何元素,可以写成() func say() -> V

swift官方文档中的函数闭包是怎么理解的?

官方文档中的16页: numbers.map({ (number: Int) -> Int in let result = 3 * number return result }) 不知道这个怎么用,更不知道它所说的要写个把奇数改成0的方法. swift官方文档中的函数闭包是怎么理解的?

Swift:闭包

一.闭包的介绍 闭包表达式(Closure Expressions) 尾随闭包(Trailing Closures) 值捕获(Capturing Values) 闭包是引用类型(Closures Are Reference Types) 闭包是自包含的函数代码块,可以在代码中被传递和使用. Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的 lambdas 函数比较相似. 闭包可以捕获和存储其所在上下文中任意常量和变量的引用. 这就是所谓的

Swift使用闭包表达式

Swift中的闭包表达式很灵活,其标准语法格式如下:{ (参数列表) ->返回值类型 in    语句组}其中,参数列表与函数中的参数列表形式一样,返回值类型类似于函数中的返回值类型,但不同的是后面有in关键字.Swift提供了多种闭包简化写法,这一节我们将介绍几种不同的形式.1.类型推断简化类型推断是Swift的强项,Swift可以根据上下文环境推断出参数类型和返回值类型.以下代码是标准形式的闭包:{(a:Int, b:Int) -> Int in    return a + b}Swift

Swift3.0 函数闭包与OC Block

刚接触Swift,如有不对的点,欢迎指正.转载请说明出处 Swift中定义一个基本函数 //定义一个函数,接收一个字符串,返回一个String类型的值 func test(name:String) -> String { return ("输出了\(name)") } //通用形式 func name(parameters) -> return type { function body } Swift 中基本的闭包函数与OC中Block的相似点 带参闭包 //OC中Bloc

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

在Apple官方的<Using Swift with Cocoa and Objectgive-C>一书中详细地介绍了如何在Objective-C中使用Swift的类以及如何在Swift中使用Objective-C中的类.在后半部分也介绍了如何在Swift中使用C函数,不过对于如何在C语言中使用Swift函数却只字未提.这里我就为大家分享一下如何在C语言中调用Swift函数. 我们首先要知道的是,所有Swift函数都属于闭包.其次,Swift函数的调用约定与Apple为Clang编译器贡献的B

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

一.Swift中闭包的简单使用 override func viewDidLoad() { super.viewDidLoad() /** 闭包和OC中的Block非常相似 OC中的block类似于匿名函数 闭包是用来定义函数 作用:Block是用于保存一段点,在需要的时候执行 闭包也是用于保存一段点,在需要的时候执行做一个耗时操作 */ /** 闭包的基本格式: { (形参列表)->() in 需要执行的代码 } */ /** * 闭包的几种格式: 1.将闭包通过实参传递给函数 2.如果闭包是