SwiftClosure

import UIKit

var str = "Hello, SwiftClosure"



/// a closure that has no parameters and return a String
var hello:() -> String = {
    return "hello"
}

/// a closure that one Int and return an Int
var double:(Int) -> (Int) = { x in
    return 2 * x
}
double(2)         //result is: 4

/// you can pass closure in your code, for example to other variables
var alsoDouble = double
alsoDouble(3)     //result is: 6



/*-------------------------------------------------------------------------------------------------
 * Remember the array sortInPlace method?                                                        *
 * 还记得 sortInPlace 函数么,让我来看一下:
 ------------------------------------------------------------------------------------------------*/

var numbers = [1,3,2,5,4,9,6]

numbers.sortInPlace()   // [1,2,3,4,5,6,9]
numbers.sortInPlace(<)  // [1,2,3,4,5,6,9]
numbers.sortInPlace(>)  // [9,6,5,4,3,2,1]
numbers.sort(>)         // [9,6,5,4,3,2,1]
numbers.sort(<)         // [1,2,3,4,5,6,9]



/*-------------------------------------------------------------------------------------------------
 * The parameter from the sortInPlace method is actually a closure. The > and < operators are
 * defined as functions,which can be referenced as closures. Here is an example for calling 
 * sortInplace that uses a closure:   
 *                                                                                                *
 * 上面方法中, sortInPlace 的参数其实就是一个闭包. 填写的参数 '>' 和 '<' 是一个闭包函数,下面这个例子将介绍闭包函数
 ------------------------------------------------------------------------------------------------*/
numbers.sortInPlace { (x, y) -> Bool in
    return x < y
 }
numbers

/* The general syntax for declaring closures is :
 
    numbers.sortInPlace { (<#Int#>, <#Int#>) -> Bool in
        <#code#>
    }
 
    if the closure does not return any value you can omit the arrow (->) and the return type:
    
    {(<#parameters#>) in
        <#statements#>
    }
 */


/*-------------------------------------------------------------------------------------------------
 * Closure can use variable and inout parameters but cannot assign default values to them.        *
 * Also closure parameters cannot have external names.                                            *
 *                                                                                                *
 * 闭包可以使用局部变量或者全局变量,但不能设置默认值,参数不能有外部名称.
 ------------------------------------------------------------------------------------------------*/
 /// examples:

var noParameterAndNoReturnValue: () -> () = {
    print("This is no Parameter And No ReturnValue closure")
}

var noParameterAndReturnValue: () -> (Int) = {
    return 1000
}

var oneParameterAndReturnValue: (Int) -> (Int) = { x -> Int in
    return x * 10
}

var multipleParametersAndReturnValue: (String,String) -> (String) =
    { (first,second) -> String in
        // do something like:
        return first + " " + second
}


/*-------------------------------------------------------------------------------------------------
 * The examples from above don't declare the type of each parameter,if you do so you don't need   *
 * to state the type of the closure because it can be inferred                                    *
 *                                                                                                *
 * 上面的例子中并没有定义每个参数的类型,但也通过编译了                                                    *
 * 当你不需要明确每个参数的类型时候,可以省略掉,因为编译器会自动推断类型
 ------------------------------------------------------------------------------------------------*/

var noParameterAndNoReturnValue_WithNoState = {
    print("Hello!")
}

var noParameterAndReturnValue_WithNoState = { () -> Int in
    return 1000
}

var oneParameterAndReturnValue_WithNoState = { (x: Int) -> Int in
    return x % 10
}

var multipleParametersAndReturnValue_WithNoState =
    { (first: String, second: String) -> String in
        return first + " " + second
}


//MARK: - Shorthand Parameter Names    进一步简化参数名
/*-------------------------------------------------------------------------------------------------
 * Swift provides shorthand parameter names for closures. You can refer to the parameters as :    *
 * $0,$1,$2 and so on.To use shorthand parameter names ignore the first part of the declaration.  *
 *                                                                                                *
 * Swift 提供为闭包的参数名提供了简写: $0,$1,$2...等等, $0代表第一个参数,以此类推. 例子如下:
 ------------------------------------------------------------------------------------------------*/
// example:

numbers.sort({return $0 < $1})

var _double:(Int) -> (Int) = {
    return $0 * 2
}

var _sum:(Int,Int) -> (Int) = {
    return $0 + $1
}

_double(2)      // result is 4
_sum(2, 3)      // result is 5


//MARK: - Capturing Values
/*-------------------------------------------------------------------------------------------------
 * In the beginning of the chapter I mentioned that closures can capture values.                  *
 * Let's see What means:
 *                                                                                                *
 *
 ------------------------------------------------------------------------------------------------*/
var number = 0

var addOne = {
    number += 1
}

var printNumber = {
    print(number)
}

printNumber()  // result is 0
addOne()       // number is 1
printNumber()  // result is 1
addOne()       // number is 2
addOne()       // number is 3
addOne()       // number is 4
printNumber()  // result is 4

/*------------------------------------------------------------------------------------------------
 * So a closure can remember the reference of a variable or constant from its context and use it *
 * when it's called. In the example above the number variable is in the global context so it     *
 * would have been destroyed only when the program would stop executing.  Let's look at another  *
 * example, in which a closure captures a variable that is not in the global context:            *
 *                                                                                               *
 * 闭包可以在调用它的时候从引用中记住变量或者常量,在上面的例子中,变量在全局使用,只有当程序停止时才被销毁          *
 * 接下来,让我们看下一个例子,闭包捕获一个局部变量,而非全局变量                                             *
 ------------------------------------------------------------------------------------------------*/
// example:

func makIterator(start:Int, step: Int) -> () ->Int {
    var i = start
    return {
        let curretnValue = i
        i += step
        return curretnValue
    }
}

var iterator = makIterator(1, step: 1)

iterator()         // result is 1
iterator()         // result is 2
iterator()         // result is 3

var anotherIterator = makIterator(1, step: 3)

anotherIterator()  // result is 1
anotherIterator()  // result is 4
anotherIterator()  // result is 7
anotherIterator()  // result is 10


//MARK: - Trailing Closure Syntax
/*-------------------------------------------------------------------------------------------------
 * If the last parameter of a cunction is a closure, you can write it after the function call     *
 *
 * 如果函数的最后一个参数是闭包,你可以在函数调用之后写它。                                                *
 ------------------------------------------------------------------------------------------------*/
// example:

//numbers.sort( $0 < $1 )
func sum(from:Int, to: Int, f:(Int) -> (Int)) -> Int {
    var sum = 0
    for i in from...to {
        sum += f(i)
    }
    return sum
}

sum(1, to: 5) {
    $0
}  // the sum of the first 10 numbers   / result is 15

sum(1, to: 5) {
    $0 * $0
}  // the sum of the first 10 squares   / result is 55


//MARK: - Closure are reference typs
/*-------------------------------------------------------------------------------------------------
 * Closures are reference types. This means that when you assign a closure to more than one      *
 * variable they will refer to the same closure. This is different form value type which make    *
 * a copy when you assign them to another variable or constant.
 *                                                                                               *
 * 闭包是引用类型,这意味着当你使用多个参数时也使用同一闭包,这是一个当你引用其他变量或常量时的不同形式的值类型
 ------------------------------------------------------------------------------------------------*/
/// example:

/// a closure that take one Int and return on Int
var __double:(Int) -> (Int) = { x in
    return 2 * x
}



//MARK: - Implicit Return Values
/*-------------------------------------------------------------------------------------------------
 * Closures that have only one statement will return the result of that statement.                *
 * To do that simply omit the return keyword.
 *                                                                                               *
 * 如果闭包只有一个参数且返回也只有一个参数,可以将 return 关键字省略
 ------------------------------------------------------------------------------------------------*/

let array = [1,3,5,7,2]
array.sort { $0 < $1 }



/*-------------------------------------------------------------------------------------------------
 * A higher order function is a function that does at least one of the follwing
 *  1. tabkes  a function as input
 *  2. outputs a function
 * Swfit has three important higher order functions implemented for arrays: map, filtr and reduce.
 ------------------------------------------------------------------------------------------------*/

//MARK: -  Map:
/// Map transforms an array using a function

/// This is Map method
/// func map<U>(transform: (T) -> U) -> [U]

/*

 [x1,x2,...,xn].map(f) -> [f(x1),f(x2),...,f(xn)]

*/


/// One way of solving this problem would be to create an empty array of strings, iterate over the original array transforming each element and adding it to the new one.
var strings:[String] = []
for number in numbers {
    strings.append("\(number)")
}
// The other way of solving this problem is by using map:

//var _strings = numbers.map { (<#Int#>) -> T in
//    <#code#>
//}
var _strings = numbers.map{ "\($0)" }


/// { "\($0)" } is the closure we provided to solve this problem. It takes one parameter and converts it into a string using string interpolation.


var _numbers    = [1, 2, 3, 4, 5, 6, 7, 8]
//var enenNumbers = _numbers.filter { (<#Int#>) -> Bool in
//    <#code#>
//}
var enenNumbers = _numbers.filter{ $0 % 2 == 0 }
// enenNumbers  = [2,4,5,8]

var sum = _numbers.reduce(0){ $0 + $1 }


/**
 *  翻译自
 *  https://www.weheartswift.com/closures/
 */

 

转载于:https://my.oschina.net/CeeYang/blog/672690

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值