在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
都希望拥有一个既有长度又有厚度的人生 有多少人能在眼花缭乱的纷繁世界下,理智的区应对? 又有几个人能将一件事坚持做10年? 想走在前面,需要明智的选择和坚守的恒心,也需要智慧和高效的自我管理!
六、函数和闭包 函数: 执行特定任务的一段代码 目的是复用,或者嵌套。 闭包:匿名函数,可以作为表达式,函数参数,函数返回值,让程序更简洁。 声明函数 func 无返回值的3种声明方式 1、省略 ->返回值类型 2、->() 空 3、->void 谁调用函数,谁负责给形参赋值。 func max(x:Int,y:Int)->Int { var z = x>y?x:y return z } func sayHi(name:String)->String { return "\(name),你好!" } 调用 var a = 6 ,b=5 var result = max(a,b) println(sayHi("renhairui")) 实战:定义个函数,返回指定的Double数值整数部分和2位小数部分 func divide(num:Double)->(String,String) { var zheng = Int64(num) var xiao = round((num-Double(zheng))*100) return ("\(zheng)","\(xiao)") } 调用 var test = divide(123.456) println("整数:\(test.0),小数:\(test.1)") 实战 找出数组中最大,最小值 func getMaxAndMin(nums:[Int])->(max:Int,min:Int) { for num in nums { if num>max { max = num } if num <min{ min = num } } return (max,min) } 调用 var nums = [20,30,5,89,100,2,6,-1] var result = getMaxAndMin(nums) println("最大值为:\(result.max),最小值为:\(result.min)") 递归函数:函数中调用自身,隐式循环,重复执行某一段代码 实战 已知数列 f(0) = 1,f(1) = 4,f(n+2) = 2*f(n+1) +f(n) func fn(n:Int)->Int { return 1 }else if n ==1{ return 4 }else{ return 2*fn(n-1)+fn(n-2) } } 递归是非常有用的,遍历某个路径下的所有文件,且深度是未知的。 外部形参 func girth(#width:Double,#height:Double)->Double { return Double(2)*(width+height) } 调用 println(girth(width:12,height:22.5)) 形参默认值 #height:Double = 20.3 println(girth(width:12)) 取消默认值形参的外部参数名 _ height:Double = 20.3 可变形参,放在参数表最后 func test (a:Int,books:String ...) { for temp in books { println(temp) } println(a) } test(3,"swift","renhairui","ok") 变量形参 func girth(var #width:Double,#height:Double)->Double { width = (width + height)*2 return width } // 避免函数体内 重新定义新变量 调用 var w = 3.2 println(girth(width:w,height:12.9)) println(w) // 3.2
inout 形参 函数体内可以修改 参数的值 func swap(inout a:Int,inout b:Int) { let tmp = a a = b b = temp } &对参数进行赋值才行, 调用 var a = 6 ,b= 9 swap(&a,&b) 已经实现交换! 实质:强制传递变量指针。 不管是值类型的参数还是引用类型的参数,swift 都只是将参数的副本传入函数内, 值类型参数传递-->值本身副本 引用类型参数传递-->引用的副本 函数类型 var myfun:(Int,Int)->Int // 类型是 (Int,Int)->Int 一般会把一个函数复制给它 变量类型要一致 函数类型的形参就是在调用函数时,动态传入函数,命令模式! 函数类型可以作为返回值类型 实战 func square(val:Int)->Int { return val * val } func cube (val:Int)->Int { return val* val *val } // 计算阶乘 func factorial (val:Int)->Int { var result = 1 for index in 2...val { result *=index } return result } 定义函数:返回值类型 (Int)->Int func getMathFunc (#type:String)->(Int)->Int { switch(type) { case "sqsuare": return square case "cube": return cube defalut: return factorial } } 调用 var mathFunc = getMathFunc (tpye:"cube") // 输出 125 println(mathFunc(5)) mathFunc = getMathFunc(type:"other") println(mathFunc(5)) //120 函数重载 多个同名函数,只是参数表,返回值类型不同 闭包 1、无func 无函数名 2、使用in关键字(可省略) 3、第一个花括号,移动到形参表的圆括号之前 4、省略return 5、省略参数名 6、$0 $1代表参数 var square:(Int)->Int = {$0*$1} println(square(5)) // 25 尾随闭包 trailing closure 如果调用函数的最后一个参数是闭包,就将{}提出来放在最后 someFunc (20,{}) 这种--> someFunc(20){} func map (var #data:[Int],#fn:(Int)->Int)->[Int] { for var i= 0, len = data.count;i<len:i++ { data[i] = fn(data[i]) } return data } var dataArr = [3,4,6,5,7] var rvt1 = map(data:dataArr){$0*$0} // 计算元素平方 var rvt2 = map(data:dataArr){$0*$0*$0} //计算元素立方 // 计算元素阶乘 不能省略return var rvt3 = map(data:dataArr){ for index in 2...$0 { result * = index } return result 捕获 :闭包 可以访问或修改上下文中的变量和常量(只能访问不能修改) 即使作用域不存在也没关系 常用于 嵌套函数中 func makeArray(ele:String)->()->[String] { var arr:[String]=[] func addElement() ->[String] { return arr } } 上边代码中 arr ,ele捕捉了上下文中的变量,每个闭包会持有一个它捕获的变量副本 调用 let addBody = makeArray("renhairui") println(addBody) // [renhairui] println(addBody) //[renhairui,renhairui] let addOther = makeArray("孙悟空") println(addOther) // [孙悟空] println(addOther) // [孙悟空,孙悟空] 输出是两个孙悟空 闭包是引用类型,所以,把一个闭包复制给两个引用变量时,程序并不会复制他们,让他们都指向同一个闭包 let addTest = addOther println(addTest)// [孙悟空,孙悟空,孙悟空] println(addTest)// [孙悟空,孙悟空,孙悟空,孙悟空]
|
请发表评论