Swift学习笔记-函数和闭包(2)

//1.函数类型
//定义一个变量(Int,Int) -> Int
var myFun : (Int ,Int) -> Int
//定义一个变量(String)-> Void
var test : (String) -> Void

//计算一个乘方的函数
func pow(#base : Int, #exponent : Int) -> Int
{
    var result = 1
    for i in 1...exponent
    {
        result *= base
    }
    return result
}

//将pow函数赋值给myFun,把myFun当成pow使用
myFun = pow
println("\(myFun(3,4))")//81

//定义一个计算面积的函数
func area(#width : Int, #height : Int) -> Int
{
    return width * height
}
myFun = area
println(myFun(3,6))//18

//2.使用函数类型作为形参类型
func map(var #data : [Int],#fn : (Int) ->Int) ->[Int]
{
    //遍历data数组中的每一个元素,并用fn函数对data[i]进行计算
    //然后将计算结果作为新的数组元素
    for var i = 0, len = data.count ; i < len; i++
    {
        data[i] = fn(data[i])
    }
    return data
}

//定义一个计算平方的函数
func square(val: Int) ->Int
{
    return val * val
}

var data : Array = [3,5,4,7,9]
println("\(map(data:data,fn:square))")//[9, 25, 16, 49, 81]

//3.使用函数类型作为返回值类型
//计算平方的
func square1(val : Int) -> Int
{
    return val * val
}
//计算立方的
func cube(val : Int) -> Int
{
    return val * val * val
}
//定义一个返回值类型为(Int)-> Int
func getMathFunc(#type:String) ->(Int) ->Int
{
    switch (type)
    {
        case "square":
        return square1
        default:
        return cube

    }
}
var mathFunc = getMathFunc(type: "square")
println(mathFunc(5))//25
//3.当函数名相同,形参列表或者返回值类型不同,都是两个不同的函数,被称为函数重载,注意包含了个数可变的形参
func test(msg :String)
{
    println("这是test()函数")
}
func text(booksName:String...)
{
    println("个数可变形参test()")
}
//报错
//test()
//test("b","a")

//4.嵌套函数,在函数体内部定义的函数
func getMath(#type:String) ->(Int) ->Int
{
    //定义一个计算平方的函数
    func square(val : Int) -> Int
    {
        return val * val
    }

    func cube(val:Int) -> Int
    {
        return val * val * val
    }

    switch (type)
    {
        case "squ":
        return square
    default:
        return cube
    }
}
var mathFun = getMath(type: "squ")
println(mathFun(5))//25
var math = getMath(type: "othe")
println(math(5))//125

//函数闭包表达式
/**
*  1.无需func关键字,无需指定函数名
* 2.定义闭包需要额外使用in关键字
* 3.定义闭包的第一个花括号要移到形参列表的圆括号之前
*/

func getMat(#type:String) ->(Int) ->Int
{
    switch (type)
    {
        case "squ":
            return {
                (val:Int) -> Int in
                return val * val
        }
    default:
        return {(val : Int) -> Int in
            return val * val * val}
    }
}

//2,调用闭包(使用闭包返回值)
//定义一个闭包,并为闭包表达式的形参定义外部形参名
//然后将闭包赋值给square2变量
var square2 = { (value val:Int) ->Int in
    return val * val
}
println(square2(4))//16

//使用闭包表达式定义闭包,并在闭包表达式后面添加圆括号来调用该闭包
var result2 = {(#base : Int,#exponent : Int) -> Int in
    var result = 1
    for i in 1...exponent
    {
        result *= base
    }
    return result
}(4,5)
println(result2)//1024

//3.利用上下文推断类型
//swift可以推断闭包表达式的形参类型,返回值类型
//闭包表达式可以省略形参类型,返回值类型
var square3:(Int) ->Int = {val in return val * val}
println(square3(4))//16

var result4:Int = { base,exponent in
    var result = 1
    for i in 1...exponent
    {
        result *= base
    }
    return result
    }(4,5)
println(result4)//1024

//省略return,当闭包表达式只有一行代码的时候,可以省略return关键字
var squrae4 : (Int) -> Int = {val in val * val}
println(squrae4(5))//5

//4.尾随闭包
func map1(var #data : [Int],fn : (Int) ->Int) -> [Int]
{
    //遍历data数组的每一元素,使用fn函数对data[i]进行计算
    for var i = 0 ,len = data.count; i < len; i++
    {
        data[i] = fn(data[i])
    }
    return data
}

var data1 = [3,4,8,9,14,15,16]
println("计算数组的平方")

var rvt1 = map1(data: data){$0 * $0}
println(rvt1)//[9, 25, 16, 49, 81]
// $0 ,$1,$2,代表闭包函数的第一,23个形参 
var rvt2 = map1(data: data1){
    var result = 1
    for index in 2...$0
    {
        result *= index
    }
    return result
}

println(rvt2)//[6, 24, 40320, 362880, 87178291200, 1307674368000, 20922789888000]

//5.捕捉上下文德变量和常量
//定义一个返回值类型是()->[String]
func makeArray(ele:String) -> () ->[String]
{
//创建一个不含任何函数的数组
    var arr:[String] = []
    func addElement() ->[String]
    {
        arr.append(ele)
        return arr
    }
    return addElement
}

let add1 = makeArray("good")
println(add1())//[good]
println(add1())//[good, good]

你可能感兴趣的:(Swift)