Swift 中的函数和闭包

函数 - 常量参数

/*
1.func 函数关键字
2.两个参数变量  value和value1都是常量,不能修改
3.SayHello("Hello", value1: "Swift") 调用函数的方法

*/
func SayHello(value :String,value1 :String) {
    let str = value + " " + value1
    print(str)
}

SayHello("Hello", value1: "Swift") // 运行结果:Hello Swift

函数 - 变量参数

// 2 函数 - 变量参数

func SayHello(var value :String) {
    value = "麦迪文"   // value 是被var修改,value是可变变量
    print(value)
}

SayHello("Hello")     // return:麦迪文

函数 - 参数默认值

// 3 函数  - 参数默认值
func SayHello(value: String = "迦罗娜·哈弗欧森") {
    print("value=\(value)")
}

SayHello("古尔丹")      // 带参数,return:value=古尔丹
SayHello()             // 不带参数,return:value=迦罗娜·哈弗欧森

函数 - 可变参数

func SayHello(values :Double...) {
    for temp in values {
        print("temp=\(temp)")
    }
}

SayHello(1.1,1.2,1.3)

运行结果:

temp=1.1
temp=1.2
temp=1.3

func HelloWarcraft(values :String...) {
    for temp in values {
        print("temp=\(temp)")
    }
}

HelloWarcraft("奥格瑞姆·毁灭之锤","迦罗娜","古尔丹","杜隆坦","安杜因·洛萨","莱恩·乌瑞恩","麦迪文","卡德加")

运行结果:

temp=奥格瑞姆·毁灭之锤
temp=迦罗娜
temp=古尔丹
temp=杜隆坦
temp=安杜因·洛萨
temp=莱恩·乌瑞恩
temp=麦迪文
temp=卡德加

函数 - 外部参数名

// 函数 - 外部参数名

// joinStr value1 :String 是一个参数
func SayHello(value :String,joinStr value1:String) {
    let str = value + " " + value1
    print("str=\(str)")
}

SayHello("Hello", joinStr: "Swift")  // return:str=Hello Swift

函数 - 输入输出参数

// 函数 - 输入输出参数

// 说明:inout 修改的变量,函数内部可以直接修改,其外部可以获取到
func SayHello(inout value:String) {
    value = "Hello Swift"
}

var str = "Hello"
SayHello(&str) // 此时传递字符串的地址
print(str)     // return:Hello Swift

函数返回值 - 元组

// 函数返回值  - 元组
// 返回元组
func SayHello(value :String,nums value1:String) ->(String,String) {
    return (value,value1)
}
var (A,B) = SayHello("Hello", nums: "Swift")
print("A=\(A),B=\(B)")  // return: A=Hello,B=Swift

函数返回值 - 函数

// 函数返回值 - 函数

// 自加函数
func Add(num : Int) -> Int {
    return num + 1
}

// 自减函数
func Minus(num :Int) -> Int {
    return num - 1
}

// 定义返回函数类型
func SayHello(num :Bool) ->(Int) ->Int {  // 其中(Int) -> Int返回参数为整型,返回值为整形的
    return num ? Add : Minus
}

var num = 10
var fun:(Int)->Int = SayHello(num > 5);

num = fun(num)

print("num=\(num)") // return:num=11

函数类型

// 函数类型

/* 
1.func 是函数关键字
2.Say是函数名,表示函数的地址
3.Say函数,参数是整形,返回值为布尔类型
*/
func Say(num:Int) ->Bool {
    return num > 10
}

/*
1.Say是函数名的地址
2.(Int) ->Bool 表示函数类型,参数为整形,返回值布尔类型
3.By是函数变量(参数为整形,返回值布尔类型),指向函数名(Say)
*/
var By:(Int) ->Bool = Say

var b = By(12) // By(12) 直接调用函数
print(b)       // return:true

闭包

Swift中的闭包其实就是一个函数代码块,它和ObjC中的Block及Java中的lambda是类似的。
闭包的特点就是可以捕获和存储上下文中的常量或者变量的引用,即使这些常量或者变量在原作用域已经被销毁了在代码块中仍然可以使用。

不使用闭包,使用函数

func mySum(num1:Int,num2:Int) -> Int {
    return num1 + num2
}

func myMinus(num1:Int,num2:Int) -> Int {
    return num1 - num2
}

func myCaculate(num1:Int,num2:Int,fn:(Int,Int)->Int) ->Int {
    return fn(num1,num2)
}

let (a,b) = (1,2)

var result = myCaculate(a, num2: b, fn: mySum)    // return:3
print(result)

result = myCaculate(a, num2: b, fn: myMinus)      // return:-1
print(result)

使用闭包

func myCaculate(num1:Int,num2:Int,fn:(Int,Int)->Int) ->Int {
    return fn(num1,num2)
}

let (a,b) = (1,2)

// 使用闭包
// 利用闭包表达式替代函数mySum
myCaculate(a,num2: b,fn: {(num1:Int, num2:Int) -> Int in
    return num1 + num2  // return:3
})

// 利用闭包表达式替代函数myMinus
myCaculate(a, num2: b, fn: {(num1:Int,num2:Int) -> Int in
    return num1 - num2  // return:-1
})

// 闭包的简化形式
// 简化形式,根据上下文rwonua且对于单表达式闭包(只有一个语句)可以隐藏return关键字
myCaculate(a, num2: b, fn: { num1,num2 in
    num1 + num2         // return:3
})

myCaculate(a, num2: b, fn: {num1,num2 in
    num1 - num2         // return:-1
})

// 闭包继续简化,使用参数缩写
// 再次简化,使用参数名缩写,使用$0...$n代表第n个参数,并且此in关键字也省略了
myCaculate(a, num2: b, fn: {$0 + $1 }) // return:3
myCaculate(a, num2: b, fn: {$0 - $1 }) // return:-1

// 尾随闭包
// 考虑到闭包表达式的可读取性,Swift中如果一个函数的最后一个参数是一个函数类型的参数(或者说是闭包表达式),则可以将此参数写在函数括号之后,这种闭包称之为“尾随闭包”.
myCaculate(a, num2: b) {
    $0 + $1   // return:3
}

myCaculate(a, num2: b) {
    $0 - $1   // return:-1
}
// 捕获变量
// 前面说过闭包之所以称之为“闭包”,就是因为其可以捕获一定作用域内的常量或者变量进而闭合并包裹着。

func myAdd() -> () -> Int {
    var total = 0
    var step = 1
    func fn() -> Int {
        total += step
        return total
    }
    return fn
}

/*
fn捕获了total和step,尽管下面的myAdd()执行完后total和step被释放,
但是由于fn捕获了二者的副本,所以fn会随着两个变量的副本一起被存储
*/

var a = myAdd()
a() // return:1
a() // return:2,说明a中保存了total的副本(否则结果会是1)

var b = myAdd()
b() // return:1,说明a和b单独保存了total的副本(否则结果会是3)

var c=b
c() // return:2,说明闭包是引用类型,换句话说函数是引用类型(否则结果会是1)

Swift会自动决定捕获变量或者常量副本的拷贝类型(值拷贝或者引用拷贝)而不需要开发者关心
被捕获的变量或者常量的内存管理同样是由Swift来管理,我们不用关心,例如当上面的函数a不再使用了,那么fn捕获的两个变量也就释放了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容