函数的定义与调用
所有的这些信息汇总起来成为函数的定义,并以func作为前缀。指定函数返回类型时,用返回箭头->后跟返回类型的名称方式来表示。
func greet(person:String) -> String {
let greeting = "Hello" + person + "!"
return greeting
}
调用:
print(greet(person: "Ann"))
函数参数与返回值
无参数函数
函数可以没有参数:
func sayHelloWorld()-> String{
return "hello,world"
}
多参数函数
函数可以有多种输入参数,这些参数被包含在函数的括号之中,以逗逗号分隔:
func greet(person:String,alreadyGreeted:Bool) -> String {
if alreadyGreeted {
return "hello"
}else {
return "world"
}
}
无返回值函数
函数可以没有返回值
func greet(person:String) {
print("Hello,\(person)")
}
多重返回值函数
可以用元组类型让多个值作为一个复合只从函数中返回。
func minMax(array:[Int]) -> (min:Int ,max:Int) {
var currentMin = array[0]
var currentMax = array[0]
for value in array {
if value < currentMin {
currentMin = value
}else if value > currentMax{
currentMax = value
}
}
return (currentMin,currentMax)
}
可选元组返回类型
如果函数返回的元组类型有可能整个元组都没有值,可以使用可选元组返回类型反映整个元组可以是nil的事实。为了安全的处理这个空数组问题,将函数改写为使用可选元组返回类型:
func minMax(array:[Int]) -> (min:Int ,max:Int)? {
var currentMin = array[0]
var currentMax = array[0]
for value in array {
if value < currentMin {
currentMin = value
}else if value > currentMax{
currentMax = value
}
}
return (currentMin,currentMax)
}
函数参数标签和参数名称
每个函数参数都有一个参数标签以及一个参数名称。参数标签在调用函数的时候使用;调用的时候需要将函数的参数标签写在对应的参数前面。参数名称在函数的实现中使用。默认情况下,函数参数使用参数名称来作为它们的参数标签。所有的参数都必须有一个独一无二的名字。虽然多个参数拥有同样的参数标签是可能的,但是一个唯一的函数标签能使你的代码更具可读性。
指定参数标签
func greet(person:String,from hometown:String) -> String {
let greeting = "Hello" + person + "!"
return greeting
}
参数标签的使用能够让一个函数在调用时更有表达力,更类似自然语言,并且保持了函数内部的可读性以及清晰的意图。
忽略参数标签
如果不希望为某个参数添加一个标签,可以使用一个下划线来代替一个明确的参数标签。
如果一个参数有一个标签,那么在调用的时候必须使用标签来标记这个参数。
func greet(_ person:String,from hometown:String) -> String {
let greeting = "Hello" + person + "!"
return greeting
}
默认参数值
可以在函数体中通过给参数赋值来为任意一个参数定义默认值。当默认值被定义后,调用这个函数时可以忽略这个参数。
func someFunction(parameterWithoutDefault:Int ,parameterWithDefault:Int = 12) {
}
如果你在调用时候不传入第二个参数,parameterWithDefault会值为12传入到函数体中。将不带有默认值的参数放在函数参数列表的最前。一般来说,没有默认值的参数更加重要,将不带默认值的参数放在最前保证在函数调用时,非默认参数的顺序是一致的,同时也使得相同的函数在不同情况下调用时显得更为清晰
可变参数
一个可变参数可以接受零个或者多个值。函数调用时,可以用可变参数来指定函数参数可以被传入不确定数量的输入值。通过在变量类型名后加入(...)的方法来定义可变参数。
func arithmeticMean(_ numbers:Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
输入输出参数
函数参数默认是常量。试图在函数体中更改参数值将会导致编译错误。这意味着你不能错误的更改参数值。如果想要一个函数可以修改参数值,并想要在这些修改在函数调用结束后仍然存在,那么就应该把这个参数定义为输入输出函数。
定义一个输入输出函数时,在参数定义前加inout关键字。一个输入输出参数有传入函数的值,这个值被函数修改,然后被传出函数,替换原来的值。
只能传递变量给输入输出参数。不能传入常量或者字面量,因为这些量是不能被修改的。当传入的参数作为输入输出参数时,需要在参数名前加&符,表示这个值可以被函数修改。
func swpaTwoInts(_ a: inout Int,_ b:inout Int) {
let temp = a
a = b
b = temp
}
var someInt = 3
var anotherInt = 107
swpaTwoInts(&someInt, &anotherInt)
print("\(someInt) \(anotherInt)")
函数类型
每个函数都有特定的函数类型,函数的类型由函数的参数类型和返回类型组成。
例如:
func addTwoInts(_ a: Int,_ b: Int) -> Int {
return a + b
}
func multiplyTwoInts(_ a: Int,_ b:Int ) -> Int {
return a * b
}
这个例子中函数类型是(Int,Int)->Int。
下面的另一个例子,一个没有参数和返回值的函数:
func printHelloWorld() {
print("hello ,world")
}
这个函数的类型是:()->Void。
使用函数类型
在swift中,使用函数类型就像使用其他类型一样。
let mathFunction:(Int,Int)->Int = addTwoInts
addTwoInts和mathFunction有同样的类型,所以这个赋值过程在swift类型检查中式允许的,可以使用mathFunction来调用被赋值的函数:
print(mathFunction(3,3))
有相同匹配类型的不同函数可以被赋值给同一个变量,就像非函数类型的变量一样,可以让swift来推断其函数类型:
let anotherMathFunction = addTwoInts
函数类型作为参数类型
func printMathResult(_ mathFunction:(Int,Int)->Int,_ a:Int,_ b:Int) {
print("\(mathFunction(a,b))")
}
函数的作用就是输出另一个适当类型的数学函数的调用结果。他不关心出入函数是如何实现的,只关心出入的函数是不是一个正确的类型。
函数类型作为返回类型
可以用函数类型作为另一个函数的返回类型。需要做的是在返回箭头后写一个完整的函数类型。
func stepForward(_ input: Int) -> Int {
return input + 1
}
func stepBackward(_ input: Int) -> Int {
return input - 1
}
如下的函数,它的返回类型是(Int)->Int类型的函数。
func chooseStepFunction(backward:Bool) -> (Int)->Int {
return backward ? stepBackward : stepForward
}
现在可以用这个函数来获取两个函数其中的一个:
var currentValue = 3
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
print("\(moveNearerToZero(3))")
嵌套函数
默认情况下,嵌套函数时对外界不可见的,但是可以被它们的外围函数调用。一个外围函数也可以返回它的某个嵌套函数,使得这个函数可以在其他域中被使用。
func chooseStepFunction(backward:Bool) -> (Int)->Int {
func stepForward(input:Int ) -> Int {return input + 1}
func stepBackward(input:Int ) -> Int {return input - 1}
return backward ? stepBackward : stepForward
}
取自《the swift programming language》中文版