美文网首页
Swift:函数与闭包(block)

Swift:函数与闭包(block)

作者: 厨子 | 来源:发表于2016-04-21 16:38 被阅读614次
    Functions and Closures

    github:Swift基础实例
    github:SwiftBasicTableView

    函数
    • 函数声明
      func 声明一个函数,通过函数名来调用函数,函数如果有参数,在圆括号 () 中需要跟上相应参数。用符号 -> 把函数的参数和函数的返回值类型隔开。
    var nameAndDay = ""
    func greet(name: String, day: String, number: Int) ->String {
        return "Hello \(name), today is \(day), \(number)."
    }
    nameAndDay = greet("Swift", day: "Sunday", number: 1)
    print(nameAndDay)
    
    • 输出 Hello Swift, today is Sunday, 1.
    1. 函数返回多个值
      从函数返回多个值时,可以使用元组 tuple ,通过 名字 或 索引来访问 tuple 中的值:
    func calculate(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
        var min = scores[0]
        var max = scores[0]
        var sum = 0
        for score in scores {
            if score > max {
                max = score
            }
            else if score < min {
                min = score
            }
            sum += score
        }
        return (min,max,sum)
    }
    let statistics = calculate([5, 10, 39, 5])
    print(statistics.sum)
    print(statistics.1)
    
    1. 参数数量可变的函数
    func sumOf(numbers:Int...) ->Int {
        var sum = 0
        // numbers.count
        for number in numbers {
            sum += number
        }
        return sum
    }
    print(sumOf())
    print(sumOf(1,3,4,5))
    
    • 上面代码中,一系列的参数放在了一个数组 numbers
    1. 函数嵌套
      嵌套函数中,内层函数可以使用外层函数中的变量。一个函数中的代码如果太长,或者比较复杂,那么可以使用嵌套函数来组织组织这些代码:
    func returnFifteen() ->Int {
        var y = 10
        func add() {
            y += 5
        }
        add()
        return y
    }
    print(returnFifteen())
    
    1. 返回函数
      Swift 的函数是第一类类型first-class type,这意味着一个函数可以把其他函数作为它的返回值:
    func makeIncrementer() ->((Int)->Int) {
        func addOne(number:Int) ->Int {
            return 1 + number
        }
        return addOne
    }
    var increment = makeIncrementer()
    print(increment(7))
    
    • 在函数 makeIncrementer 中,构造了另外一个函数 addOne 并将其返回,返回函数名就可以(猜测,可能返回的是函数指针)
    1. 函数作为参数
      一个函数可以作为另外一个函数的参数,传递进去:
    func lessThanTen(number:Int) ->Bool {
        return number < 10
    }
    func hasAnyMatches(list:[Int], condition:(Int) ->Bool) ->Bool {
        
        for item in list {
            if condition(item) {
                return true
            }
        }
        return false
    }
    var numbers = [20,13,4,9]
    hasAnyMatches(numbers, condition: lessThanTen)
    
    • 传递函数时,也是只传递名称就可以
    闭包(block)

    闭包格式

    { (参数) -> 返回值类型 in
        statements
    }```
    - 有名称的闭包
    函数是特殊的闭包:代码块可以稍后被调用。上面的嵌套函数,就属于是有名字的闭包,无名的闭包(`匿名闭包`)是不写名字(比如`函数名`),然后把代码放在大括号`{}`中。再看下面的栗子:假设我们要写两个函数,一个计算两个数的平方的平均值,一个计算两个数的立方的平均值,一般做法是:
    

    func square(a:Float) ->Float {
    return aa
    }
    func cube(a:Float) ->Float {
    return a
    a*a
    }
    func averageSumOfSquare(a:Float, b:Float) ->Float {
    return (square(a) + square(b))/2.0
    }
    func averageSumOfCube(a:Float, b:Float) ->Float {
    return (cube(a) + cube(b)) / 2.0
    }
    averageSumOfSquare(1.0, b: 3.0)
    averageSumOfCube(2.0, b: 3.0)

    上面函数 `averageSumOfSquare` 和 `averageSumOfCube` 唯一不同之处就是分别调用了平方函数和立方函数。如果我们可以定义这样一个函数,这个函数以两个数和一个使用这两个数的函数作为参数,来计算平均值而不是重复调用将会非常好,我们可以使用闭包作为函数参数:
    

    func averageOfSum(a:Float, b:Float, f:(Float ->Float)) ->Float {
    return (f(a) + f(b))/2.0
    }
    averageOfSum(2.0, b: 3.0, f: square)
    averageOfSum(3.0, b: 3.0, f: cube)

       - `square`和`cube`可以被看做有名称的闭包
    
    2. 无名称闭包
    下面说一下无名内联闭包,代码也是写在大括号 `{}` 中,代码用 `in` 将参数和返回类型与实现(`body`)隔开:
    

    // 注意格式,每一行换行的地方
    individualScores.map({
    (number:Int) ->Int in
    let result = number+3
    return result
    })

    
    3. 闭包简写
    如果闭包的类型是已知的,比如 `delegate`,那么可以删掉闭包的`参数类型`或`返回类型`,或者两者都删掉。单语句闭包隐式返回这条语句的执行结果.
    

    individualScores.map({
    number in number+3})
    print(individualScores)
    let mappedScores = individualScores.map({
    number in number+3})

       - 数组 `individualScores` 中的值没有变化,而是调用 `.map` 之后会返回一个新的数组,新数组`mappedScores`中的值会每个都加3
    
       我们还可以忽略参数名,使用默认参数名`$0`,如果有多个参数,使用 `$n` 作为第 `n-1` 个参数:
    

    individualScores.map({
    $0+3})

    如果某一个函数的最后一个参数是闭包,那么这个闭包可以直接出现在圆括号`()`之后,例如下面的升序排序:
    

    let sortedNumbers = individualScores.sort(){
    $0 < $1
    }
    print(sortedNumbers)

    如果某一个函数唯一的参数是闭包,那么可以把圆括号`()`省略掉:
    

    let sortedNumbers = individualScores.sort {
    $0 < $1
    }
    print(sortedNumbers)

    
    4. 总结
    >闭包是函数的一种,但闭包的真正意义是:把参数传递进一个块(这个块是用来实现闭包的),然后对参数就行修改,修改过之后,再使用。总结为一句话,传递参数-->修改-->使用

    相关文章

      网友评论

          本文标题:Swift:函数与闭包(block)

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