Swift函数与闭包-(函数)

Swift函数与闭包

函数

定义函数

swift的函数声明使用func关键字,当我们声明一个函数时,我们需要指定其返回值类型,并且在函数中按照指定的类型返回数据。

函数声明(Function)可以是在类class当中的,也可以独立在class外使用。当函数声明在类当中时,我们通常称其为方法(Method)。

下面这个函数是计算两个整形数据的值的:

1
2
3
4
5
func intAdder(x: Int, y:Int) -> Int {
return x + y
}
let intNum = intAdder(10, y: 20)
print(intNum)

在这个函数当中,我们指定了它的参数名与参数类型(x:Int, y:Int)以及函数的返回值类型(->Int)。参数类型限定了传入参数的数据类型,而返回值则指定了返回的数据类型。在有返回值的时候,我们都是使用数据类型来指定返回类型的。在无需返回值的函数当中,我们可以指定返回值为Void或者省略返回值类型。

1
2
3
4
5
6
7
8
9
10
11
# Void
func sideEffectAdder(x:Int, y:Int) -> Void {
print("Added value is \(x + y)")
}
sideEffectAdder(3, y:4)

# leave it empty
func sideEffectAdderEmpty(x:Int, y:Int) {
print("Added value is \(x + y)")
}
sideEffectAdder(3, y:4)

参数别名

swift允许我们为函数定义外部调用的别名。那intAdder这个方法来说明:

1
2
3
4
5
6
7
8
9
func intAdder(x: Int, y:Int) -> Int {
return x + y
}
intAdder(10, y: 20)

func intAdder(first x: Int, second y:Int) -> Int {
return x + y
}
intAdder(first: 10, second: 20)

上面两个同名的function可以并列存在(事实上,函数名相同的function如果外部参数名不一样,都可以在一起共存),只是我们调用的时候可以使用不同的参数名;

需要注意的是,一旦我们给函数定义了参数别名,在调用的时候一定要使用别名传参;

同时在多个参数的时候,我们可以指定某一个或者几个参数的参数别名,只需要在调用的时候使用参数别名就好。

默认情况下,swift对于多参数的调用除了第一个参数可以不写参数名,其后续的参数都是需要写参数名的。有的时候,对于参数的顺序我们并不是太care,或者我们并不想写后续参数名,我们可以使用_的方式作为别名来写函数:

1
2
3
4
5
func intAdder (x: Int, _ y:Int) -> Int {
return x + y
}
let intNum5 = intAdder(10, 30)
print(intNum4)

不定长参数

有时候,我们传递的参数是不定个数的,这个时候我们可以使用...来指代,使用起来比较简单,直接在单参数后面加上...即可。

1
2
3
4
5
6
func sayHelloTo(names:String...)-> String{
let names = names.joinWithSeparator(" and ")
return("Hello to \(names)")
}
sayHelloTo("Jack") // Hello to Jack
sayHelloTo("Jack", "Jill") // Hello to Jack and Jill

...定义的参数列表有些类似于数组。使用的时候可以通过Array.joinWithSeparator来操作。

多参数时的不定长参数是可以在放置在参数的各个顺序的,当使用不定长参数时,不能使用_来省略参数名。当指定了多个不定长参数,我们只需要明确其参数名即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
func saySomethingToSomebody(thing: String, _ names:String...)-> String{
let names = names.joinWithSeparator(" and ")
return("Say \(thing) to \(names)")
}
saySomethingToSomebody("Morning", "Jack") // Say Morning to Jack
saySomethingToSomebody("Good night", "Jack", "Jill") // Say Good night to Jack and Jill

func saySomethingToSomebodySometimes(thing: String, names:String..., times: Int)-> String{
let names = names.joinWithSeparator(" and ")
return("Say \(thing) to \(names) \(times) times")
}
saySomethingToSomebodySometimes("Morning", names: "Jack", times: 100) // Say Morning to Jack 100 times
saySomethingToSomebodySometimes("Good night", names: "Jack", "Jill", times: 200) // Say Good night to Jack and Jill 200 times

可选型返回值

有时候,函数的逻辑不一定能返回特定类型的值,它还可能返回nil。对于这种情况,我们需要将函数的返回值类型定义成可选型。

1
2
3
4
5
6
7
8
9
10
11
func evenAdder(x:Int, _ y:Int) -> Int? {
let even = (x % 2 == 0, y % 2 == 0)
switch even{
case (true, true):
return (x + y)
default:
return nil
}
}
evenAdder(2, 4) // {Some 6}
evenAdder(2, 3) // nil

多返回值[元祖]的函数

元组是swift当中的一种数据类型。函数也可以返回这种类型。

1
2
3
4
5
6
func postDataToServer() -> (status: Int, message: String) {
return (200, "Success")
}
postDataToServer() //(.0 200, .1 "Success")
postDataToServer().status //200
postDataToServer().1 //"Success"

除了将元组类型写到返回值的地方,我们也可以通过typealias来声明一个元组作为返回值类型。

1
2
3
4
5
6
7
typealias Response = (status: Int, message: String)
func response() -> Response {
return (200, "Success")
}
response()
response().status
response().1

返回值类型为函数的函数

函数是swift的头等公民,我们可以将函数赋值给一个变量,然后将这个变量作为其它函数的返回值类型。这一点正是swift函数式编程的一种体现。

swift当中的函数可以作为变量类型来操作,我们可以通过这种特性在任何地方使用函数作为数据类型。所以,我们也可以把函数当做函数的返回值类型:

1
2
3
4
5
6
7
8
9
func capitalize(s:String) -> String {
return s.capitalizedString
}
capitalize("hello") // "Hello"

func applyToString(s:String, f:(String)->String) -> String {
return(f(s))
}
applyToString("hello", f: capitalize) // "Hello"

swift当中有很多使用函数作为返回值类型的例子。比如map,reduce,sort等等。。。

1
["a", "b", "c"].map(capitalize) // ["A", "B", "C"]

###函数嵌套

在swift当中,我们可以使用嵌套函数。

1
2
3
4
5
6
7
8
9
10
func makeLogger() -> (String) -> String {
func log(s:String) -> String {
print(s)
return(s)
}
return(log)
}

let myCustomLog = makeLogger()
myCustomLog("I am a message") // I am a message