函数 - 常量参数
/*
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捕获的两个变量也就释放了。