从零开始Swift之函数

有参数没返回值

func greet(person: String){
    print("Hello, \(person)")
}
greet(person: "Dave")

没有参数的函数,有返回值

func sayHelloWorld() -> String{
    return "hello world"
}

函数定义在函数名称后面仍然需要括号,即使它不带任何参数,当函数被调用时, 函数名称后面跟着一对空的括号。

sayHelloWorld()

多个参数

func greet(person: String, alreadyGreeted: Bool) -> String {
    if alreadyGreeted {
        return "1"
    }else{
        return "2"
    }
}

多返回值函数

可以使用元组类型作为函数的返回类型,以作为一个复合返回值的一部分返回多个值。

下面的示例定义了一个名为minMax(array :)的函数,它找到Int值数组中最小和最大的数字:

func minMax(array: [Int]) -> (min :Int, max: Int) {
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        }else if value > currentMax {
            currentMax = value
        }
    }
    
    return (currentMin, currentMax)
}

minMax(array: [1,2,3,4,5,54,87654,324567,5432,23456,76543])

可选元组返回类型

上面的minMax(array :)函数返回一个包含两个Int值的元组。 但是,该函数不会对传递的数组执行任何安全检查。 如果数组参数包含空数组,则如上所述,minMax(array :)函数在尝试访问数组[0]时将触发运行时错误。

要安全地处理空数组,使用可选的元组返回类型编写minMax(array :)函数,并在数组为空时返回值nil:

func minMax(array: [Int]) -> (min :Int, max: Int)? {
    if array.isEmpty {
        return nil
    }
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        }else if value > currentMax {
            currentMax = value
        }
    }
    
    return (currentMin, currentMax)
}
minMax(array: [1,2,3,4,5,54,87654,324567,5432,23456,76543])

参数标签

在参数前面写,用空格分割

func greet(person: String, from hometown: String) -> String{
    return "Hello \(person)! Glad you could visit from \(hometown)"
}

print(greet(person: "Bill", from: "Cupertino"))

省略参数标签

如果不想要参数的参数标签,请为该参数编写下划线(_),而不是显式参数标签。

func someFunction(_ firstParameterName: Int, secondParameterName: Int) {
    
}

someFunction(1, secondParameterName: 2)

默认参数值

您可以通过为该参数的类型之后的参数分配值来为该函数中的任何参数定义默认值。 如果定义了默认值,则可以在调用该函数时忽略该参数。

func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
    
}

someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6)
someFunction(parameterWithoutDefault: 4)// parameterWithDefault 是12

可变参数

可变参数接受指定类型的零个或多个值。 您可以使用可变参数来指定在调用函数时,参数可以传递不同数量的输入值。 通过在参数的类型名称后插入三个句点字符(...)来写入可变参数。

传递给可变参数的值在函数体内作为适当类型的数组可用。 例如,具有数字名称和Double ...类型的可变参数在函数体内可用作称为[Double]类型的数字的常数数组。

func arithmeticMean(_ numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}

arithmeticMean(1,2,3,4,5)
arithmeticMean(3,8.25,18.75)

输入 - 输出参数

默认情况下,函数参数是常量。试图从函数体内更改函数参数的值会导致编译时错误。这意味着您不能错误地更改参数的值。如果希望函数修改参数的值,并希望这些更改在函数调用结束后保留​​,请将该参数定义为in-out参数。

通过将inout参数放在参数类型之前,您可以编写一个in-out参数。输入 - 输出参数具有传递到函数的值,由函数修改,并被传回函数以替换原始值。

您只能将一个变量作为in-out参数的参数传递。您不能将常量或文字值作为参数传递,因为常量和文字不能被修改。在将变量的名称“”作为参数传递给in-out参数时,在变量的名称“”之前直接放置一个&符号(&),以指示它可以被该函数修改。

func swapTwoInts(_ a: inout Int, _ b: inout Int){
    let temporaryA = a
    a = b
    b = temporaryA
}

var a = 10
var b = 20
swapTwoInts(&a, &b)

函数类型

每一个函数都有一个明确的类型, 有参数类型和函数的返回类型组成

使用函数类型

在Swift中使用类型任何其他类型的函数类型,例如,你可以将常量或变量定义为函数类型,并未该变量分配适当的函数

func addTwoInts(_ a: Int, _ b: Int) -> Int {
    return a + b
}
var mathFunction: (Int, Int) -> Int = addTwoInts

上面那段代码的意思是定义一个名为mathFunction的变量,它的类型是一个函数, 他接收两个Int值, 并返回一个Int值. 设置这个新变量一用用成为addTwoInts函数

函数类型座位参数类型

我们可以使用诸如 (Int, Int) -> Int之类的函数类型作为另一个函数的参数类型. 这使我们能刘霞函数的实现,以便函数的调用者在调用函数时提供

func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
    print("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)

printMathResult(::_:), 第一个参数是一个函数类型,我们可以传递任意类型为该函数类型的变量当做参数

函数类型作为返回值类型

函数chooseStepFunction(backward :) ,它的返回值类型是(Int) -> Int

func stepForWard(_ input: Int) -> Int{
   return input + 1
}

func stepBackward(_ input: Int) -> Int{
    return input - 1
}

func chooseStepFunction(backward: Bool) -> (Int) -> Int{
    return backward ? stepBackward : stepForWard
}

// 调用一下chooseStepFunction(backward:) 函数
var currentValue = 3
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
moveNearerToZero

嵌套函数

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
}

var currentValue = -4
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
while currentValue != 0 {
    print("\(currentValue)...")
    currentValue = moveNearerToZero(currentValue)
}

推荐阅读更多精彩内容