• playSwift第五章(函数和闭包)


    1.函数

    可变参数放最后,var参数只在函数内有效,函数形参默认let类型,inout参数地址传递。

    函数新特性:

    (1)函数可以通过返回元组实现返回多个参数,Void表示放回空元组。

     函数类型的变量。

    (2)函数可以作另一个函数的参数。

    (3)函数可以作另一个函数的返回值,对于一个->表返回,后面的->表示返回值为一个函数。

    //////////////////////////////part1
    //函数
    func sayHello(name:String?)->String{//->String表示返回一个字符串类型
        let result = "hello,"+(name ?? "Guest")//当字符串为空时,name为guest
        return result;
    }
    
    
    var nickname:String?//声明一个可选型的字符串
    println(sayHello(nickname))
    
    //////////////////////////////part2
    //通过元祖可以返回多个值
    func maxminSores(score:[Int])->(maxscore:Int,minscore:Int)?{//返回一个可选值元祖
        if score.isEmpty{//当数组为空时
            return nil
        }
        var curmax = score[0],curmin = score[0]//初始化最大最小值为第一个数
        for score in score[1..<score.count]//1到count-1
        {
            curmax = max(curmax, score)
            curmin = min(curmin, score)
        }
        return (curmax,curmin)
    }
    
    
    var userScores:[Int]? = [12,990,572,3258,9999,1204]
    userScores = userScores ?? []//当数组为空时userScores=[]
    if let (maxV,minV) = maxminSores(userScores!){
    maxV
    minV
    }
    
    
    //////////////////////////////part3
    //保留oc特性中的外部参数名
    //#表示外表参数名跟内部一致,定义函数允许赋予默认值,有默认值的参数要放在后面
    func sayHi(userName name:String?,# greet:String,others:String=". how do you do")->String{//->String表示返回一个字符串类型
        let result = "(greet),"+(name ?? "Guest")+others//当字符串为空时,name为guest
        return result;
    }
    sayHi(userName: "forr", greet: "hi")
    //////////////////////////////part4
    //设置可变参数others:Int...    
    //函数的参数排序:先是必须的参数,再到带默认值的参数,最后是可变的参数
    //函数中的参数默认是let不可变的,且属于值传递,
    func add(var a:Int,b:Int,others:Int...)->Int{
        var result = a+b
        for num in others{
            result += num
        }
        a = 1000
        return result
    }
    var a = 2
    var res = add(a,3, 4)
    a
    ////////////////////////////part4
    //通过inout声明参数实现“址传递”
    func swapTwoInts(inout a:Int,inout b:Int){
        let t = a
        a = b
        b = t
    }
    
    var x = 0,y = 100
    x
    y
    
    swapTwoInts(&x, &y)
    x
    y
    ////////////////////////////part5
    //通过变量存在一个函数,此时给出变量的类型为:(Int,Int,Int...)->Int
    let anotherAdd:(Int,Int,Int...)->Int = add
    anotherAdd(6,3,1)
    
    
    func sayYes(){
        print("yes")
    }
    let anotherSayYes:()->() = sayYes
    sayYes()
    ////////////////////////////part6
    //将一个函数用作另一个函数的参数,:(Int)->Int表示变量的类型是一个函数类型
    func changeScores(op:(Int)->Int,inout scores:[Int]){
        for i in 0..<scores.count{
            scores[i] = op(scores[i])//调用函数op(scores[i])
        }
    }
    
    func op1(x:Int)->Int{return Int(sqrt(Double(x))*10)}
    func op2(x:Int)->Int{return Int(Double(x)/150.0*100)}
    func op3(x:Int)->Int{return x + 3}
    
    var scores1 = [36,61,78,99]
    changeScores(op1 , &scores1)
    
    var scores2 = [88,101,124,137,150]
    changeScores(op2  , &scores2)
    
    var scores3 = [59,61,76,83,95]
    changeScores(op3 , &scores3)
    
    
    //使用系统sorted对数组降序
    var arr = [Int]()
    for _ in 1...20{
        arr.append(Int(arc4random()%100))
    }
    sorted(arr)
    
    func compareTwoInts(a:Int,b:Int)->Bool{
        return a>b//降序
    }
    sorted(arr, compareTwoInts)//第二个参数传一个定义好降序规则的函数
    
    ////////////////////////////part7函数式编程
    //将一个函数用作另一个函数的返回值
    func tier1MailFee(weight:Int)->Int{
        return 1*weight;
    }
    
    func tier2MailFee(weight:Int)->Int{
        return 2*weight;
    }
    //(Int)->Int表示返回值的类型是一个函数类型
    func chooseMailFeeCalcMethod(weight:Int)->(Int)->Int{
        return (weight <= 10) ? tier1MailFee : tier2MailFee
    }
    
    func totalPrice(price:Int,weight:Int)->Int{
        let mailFeeCalc:(Int)->Int = chooseMailFeeCalcMethod(weight)//定义一个接收函数的变量
        return mailFeeCalc(weight) + price * weight//4+8
    }
    
    totalPrice(2, 4)
    totalPrice(1, 12)
    
    //函数内可嵌套函数
    //func totalPrice(price:Int,weight:Int)->Int{
    //    func chooseMailFeeCalcMethod(weight:Int)->(Int)->Int{
    //        return (weight <= 10) ? tier1MailFee : tier2MailFee
    //    }
    //    let mailFeeCalc:(Int)->Int = chooseMailFeeCalcMethod(weight)//定义一个接收函数的变量
    //    return mailFeeCalc(weight) + price * weight
    //}

    2.闭包

    嵌套函数,函数定义在函数体的内部。通过闭包可以对这种嵌套函数进行简化

    //嵌套函数
    func getMathFunc(#type:String)->
        (Int)->Int{
            func squre(num:Int)->Int{
                return num * num;
            }
            func cube(num:Int)->Int{
                return num * num * num;
            }
            switch(type){
            case "squre":
                return squre;
            default:
                return cube;
            }
    }
    
    
    var squre:(Int)->Int = getMathFunc(type: "squre");
            println(squre(4));

    (1)闭包的格式:  {函数的声明 in 方法的实现} 

    {(形参列表)->返回值类型 in

      执行表达式

    }

    (2)闭包的各种简化形式

    (3)闭包可以做一个函数的参数,最后一个参数为闭包时,可以写在函数外面(结尾闭包)。其格式: func 函数名(形参列表){函数的声明 in 方法的实现}

    ///////////////////////////////part1闭包相当匿名函数
    //闭包{(a:Int,b:Int)->Bool in return a>b}
    sorted(arr, {
        (a:Int,b:Int)->Bool in return a>b//in关键字
    })
    arr
    
    
    var strArr = ["d","cd","bcd","abcd","abc","ab","a"]
    strArr = sorted(strArr, {
        (s1:String,s2:String)->Bool in
        if countElements(s1) != countElements(s2){
            return countElements(s1) < countElements(s2)//字母个数少的在前面
        }
        return s1 < s2//升序
    })
    
    sorted(arr,
        {a,b in return a>b})//简短版
    sorted(arr,
        {$0 > $1})//降序,$0,$1表示第一二个参数
    sorted(arr, >)//操作符作函数传入,该话题后续
    ///////////////////////////////part2
    //结尾闭包trailing closure
    strArr = sorted(strArr) {
        (s1:String,s2:String)->Bool in
        if countElements(s1) != countElements(s2){
            return countElements(s1) < countElements(s2)//字母个数少的在前面
        }
        return s1 < s2//升序
    }
    //闭包内可以访问外边变量,后续相关的内存管理
    var datas = [0,1,2,3,4,5,6,7,8,9,10]
    var num = 3
    datas = sorted(datas){
        return fabs(CGFloat($0-num)) < fabs(CGFloat($1-num))
    }
    ///////////////////////////////part3
    //函数和闭包都属于引用类型,其他数据类型属于值类型
    func calcTotalMiles(todayMiles:Int)->()->Int{
        var totalMiles = 0//与一般函数中的变量差别很大,通常其他语言函数里定义的变量都是存放在栈区,调研函数后,定义的变量通通会销毁
        return {totalMiles += todayMiles;return totalMiles}//闭包
    }
    
    var dailyTwoMiles = calcTotalMiles(2)
    dailyTwoMiles()
    dailyTwoMiles()
    dailyTwoMiles()
    
    var myPlan = dailyTwoMiles
    myPlan()
    dailyTwoMiles()

     .

    //闭包的简化形式
    //        var squre:(Int)->Int = {(num) in return num * num }
    //        println(squre(4));
            
    //        var squre:(Int)->Int = {num in return num * num }
    //        println(squre(4));
            
            //省略形参名,通过$0、$1...来引用第一个、第二个参数
            var squre:(Int)->Int = {$0 * $0}
            println(squre(4));
            //
            var result:Int = {
                var result = 1;
                for i in 1...$1{
                    result *= $0;
                }
                return result;
            }(4,3)//{}表示闭包     (,)表示调用
            println("(result)")
  • 相关阅读:
    中文词频统计
    复合数据类型,英文词频统计
    Mybatis 异常:Cause: java.io.IOException: Could not find resource com.xxx.xxx.xml
    Ajax:修改了项目的ajax相关代码,点击运行没有效果
    大数据应用期末总评
    分布式并行计算MapReduce
    分布式文件系统HDFS 练习
    安装关系型数据库MySQL和大数据处理框架Hadoop
    爬虫综合大作业
    爬取全部的校园新闻
  • 原文地址:https://www.cnblogs.com/huen/p/4295449.html
Copyright © 2020-2023  润新知