美文网首页
Swift 基本语法(五)— 函数闭包

Swift 基本语法(五)— 函数闭包

作者: Eddiegooo | 来源:发表于2019-10-04 11:17 被阅读0次

    函数和闭包

    函数基本定义与使用。 可以有一个或者多个参数,可以有一个返回值,也可以有多个返回值。函数是引用类型。

    //swift 5.1新特性,隐式返回值
    func greet(person: String) -> String {
        return "hello +\(person)"  //单一表达式,在swift5.1中,可以省掉return, 直接返回"hello +\(person)"
    }
    
    //返回可选值类型
    func minMaxTuple(nums: [Int]) ->(min: Int, max: Int)? {
        if nums.count < 1 {
            return nil  //如果不是可选元组返回值类型,这里会报错
        }
        var min = nums[0]
        var max = nums[0]
        for value in nums {
            if min > value {
                min = value
            }
            if max < value {
                max = value
            }
        }
        return (min, max)
    }
    

    函数的实际参数和形式参数

    func function(_ person: String, from hometown: String) {
        /// person,hometown 形式参数名 ; from 实际参数标签。
        /// 当有实际参数标签的时候,函数调用的时候就不会显示形式参数名。function(person: "Eddie", from: "China")
        /// _ 通用实际参数标签,不指定。在调用函数的会有提示  function("Eddie", from: "China")
    }
    
    //也可以指定一个默认参数值,当有传参时,使用传的参数值,没有使用默认值
    func defaultParamFunc(defaultParam: Int = 88, num: Int) {
        print(defaultParam + num)
    }
    defaultParamFunc(defaultParam: 66, num: 4) // 66-->70
    defaultParamFunc(num: 2) //88--->90
    
    //可变形式参数
    func addNums(nums: Int ...) -> Int{
        var sum = 0
        for num in nums {
            sum += num
        }
        return sum
    }
    addNums(nums: 1,2,3,4,5)
    
    //输入输出形式参数   关键字inout。  可以直接使用并且修改。 当使用它的时候,要在其前面加一个&符号。  传入的必须是变量。   不可以有默认值,可变形式参数不可以被标记为inout类型。
    func swapTwoNums(num1: inout Int, num2: inout Int){
        let temp = num1
        num1 = num2
        num2 = temp
    }
    var a = 3, b = 5
    swapTwoNums(num1: &a, num2: &b)
    print(a,b) // 5 3
    

    函数类型.

    //内嵌函数  封装隔离效果
    func chooseStepFunction(forwardVale: Bool) -> (Int) -> Int {
        func forwardStep(step: Int) -> Int { return step + 1}
        func backWardStep(step: Int) -> Int { return step - 1}
        return forwardVale ? forwardStep : backWardStep
    }
    
    var currentValue = 4
    let stepFunc = chooseStepFunction(forwardVale: currentValue < 0)
    while currentValue != 0 {
        currentValue = stepFunc(currentValue)
    }
    //将函数当形式参数使用
    func printFunctionResult(mathFunction:(Int, Int) -> (Int), _ a: Int, _ b: Int) {
        print(mathFunction(a,b))
    }
    func addTwoNum(a: Int, b: Int) -> Int{
        return a + b
    }
    printFunctionResult(mathFunction: addTwoNum, 3, 5)
    
    闭包 和函数一样,也是引用类型

    { (参数,参数,...) -> returnType in
    表达式
    }

    let nameArray = ["zhangsan", "lisi", "wangwu", "zhaoliu"]
    func compareName(_ s1: String, _ s2: String) -> Bool {
        return s1 > s2
    }
    let result = nameArray.sorted(by: compareName)
    //print(result)
    
    //直接使用闭包
    let array = nameArray.sorted(by: {(s1: String, s2: String) -> Bool in
        return s1 > s2
    })
    //单表达式, 可以省略返回值表达式写法
    nameArray.sorted(by: {(s1: String, s2: String) -> Bool in
        s1 > s2
    })
    //根据内容自推断类型,省略类型说明符
    let simpleArray = nameArray.sorted(by: {(s1, s2) in
        s1 > s2
    })
    nameArray.sorted { (s1, s2) -> Bool in
        s1 > s2
    }
    nameArray.sorted{ s1, s2 in
        s1 > s2
    }
    //运算符形式
    nameArray.sorted(by: > )
    //单表达式 尾随闭包
    nameArray.sorted{ $0 > $1}
    

    逃逸闭包和自动闭包

    //逃逸闭包:函数调用结束后才去调用,就要标记为可逃逸的@escaping  自动闭包:@autoclosure
    var names = ["Eddiegooo", "zhangsan", "lisi", "wangwu"]
    var resultArray:[() -> String] = []
    //会报错。。
    //func someFunction(name: () -> String) {
    //    resultArray.append(name) //报错error: passing non-escaping parameter 'name' to function expecting an @escaping closure
    //}
    //可逃逸闭包
    func someFunction(name: @escaping () -> String) {
        resultArray.append(name)
    }
    
    //someFunction(name: "zhaoliu")  //error: cannot convert value of type 'String' to expected argument type '() -> String'
    someFunction(name: { "Eddie" })
    
    //如果将闭包设置为自动闭包类型,调用时候可以直接传字符串
    func someFunction1(name: @autoclosure @escaping () -> String) {
        resultArray.append(name)
    }
    
    //逃逸闭包如果使用属性,必须显式使用self
    class someClass {
        var somename: String = "Chole"
        func someFunc() {
            someFunction(name: { self.somename })
        }
    }
    
    

    高阶函数,主要就三个map, reduce, filter

    //高阶函数
    //map 函数。  给每一个元素都做同样的操作 得到一个新的数组
    let nums = [1, 2, 4, 5]
    let newNums = nums.map { $0 * 10 }
    print(newNums)  // [10, 20, 40, 50]
    
    //filter条件筛选。  不符合的直接舍弃
    print(nums.filter({ $0 > 3 })) //[4, 5]
    
    //reduce  在一个初始值的基础上 累加所有元素
    print(nums.reduce(30, { $0 + $1 }))  //42  = 30+1+2+4+5
    
    //直接合并成一组数据数组
    let arrayNums = [[1,2,3], [4,5,6], [7,8,9]]
    print(arrayNums.flatMap({$0.map({$0 * 10})}))  // [10, 20, 30, 40, 50, 60, 70, 80, 90]
    
    let nameArray: [String?] = ["zhangsan", nil, "lisi", "wangzu", nil]
    print(nameArray.count) //5
    print(nameArray.flatMap({ $0 }))  == print(nameArray.compactMap({ $0 }))  //["zhangsan", "lisi", "wangzu"]  获取非空元素新集合
    print(nameArray.flatMap({ $0?.count })) //[8, 4, 6] //非空元素的个数
    

    相关文章

      网友评论

          本文标题:Swift 基本语法(五)— 函数闭包

          本文链接:https://www.haomeiwen.com/subject/bablpctx.html