Swift 笔记:函数


Apple-Swift-logo

函数是一段完成特定任务的独立代码片段。在 Swift 中,每个函数都有一个由函数的参数值类型和返回值类型组成的类型。函数的定义可以写在其他函数定义中,这样可以在嵌套函数范围内实现功能封装。

函数的定义与调用

定义一个函数时,可以定义一个或多个有名字和类型的值,作为函数的输入,称为参数,也可以定义某种类型的值作为函数执行结束时的输出,称为返回类型。要使用一个函数时,用函数名来“调用”这个函数,并传给它匹配的输入值(称作实参),函数的实参必须与函数参数表里参数的顺序一致。

func sayHello(name: String) -> String {
    return "Hello, " + name + "!"
}
print(sayHello(name: "Ryan"))

函数参数与返回值

函数可以没有参数:函数名后添加一对圆括号即可,调用时也需要在在函数名后写一对圆括号:

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

函数可以有多种输入参数,这些参数被包含在函数的括号之中,以逗号分隔:

func greet(person: String, alreadyGreeted: Bool) -> String {
    ……
}

函数可以没有返回值:

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

被调用时,一个函数的返回值可以被忽略,但定义了有返回值的函数必须返回一个值,如果在函数定义底部没有返回任何值,将导致编译时错误(compile-time error)。

可以用元组(tuple)类型让多个值作为一个复合值从函数中返回:

func minMax(array: [Int]) -> (min: Int, max: Int) {
    ……
}

如果函数返回的元组类型有可能整个元组都“没有值”,可以使用可选的( optional )元组返回类型反映整个元组可以是nil的事实。可以通过在元组类型的右括号后放置一个问号来定义一个可选元组,例如 (Int, Int)?(String, Int, Bool)?

注意:
可选元组类型如 (Int, Int)? 与元组包含可选类型如 (Int?, Int?) 是不同的.可选的元组类型,整个元组是可选的,而不只是元组中的每个元素值。

函数参数标签和参数名称

每个函数参数都有一个参数标签(argument label)以及一个参数名称(parameter name)。参数标签在调用函数的时候使用;调用的时候需要将函数的参数标签写在对应的参数前面。参数名称在函数的实现中使用。默认情况下,函数参数使用参数名称来作为它们的参数标签。

参数名称必须是唯一的,虽然多个参数拥有同样的参数标签是可能的,但是一个唯一的函数标签能够使代码更具可读性。

指定参数标签

在参数名称前指定它的参数标签,中间以空格分隔:

func someFunction(argumentLabel parameterName: Int) {
    // 在函数体内,parameterName 代表参数值
}

忽略参数标签

如果不希望为某个参数添加一个标签,可以使用一个下划线(_)来代替一个明确的参数标签:

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

默认参数值

可以在函数体中通过给参数赋值来为任意一个参数定义默认值(Deafult Value)。当默认值被定义后,调用这个函数时可以忽略这个参数。

一般来说,没有默认值的参数更加的重要,将不带默认值的参数放在参数列表的最前面。

可变参数

可变参数(variadic parameter)可以授受零个或多个值,通过在变量类型名后面加入(...)的方式来定义可变参数。可变参数的传入值在函数体中变为此类型的一个数组。

func arithmeticMean(_ numbers: Double...) -> Double {
    ……
}

注意:
一个函数最多只能拥有一个可变参数。

输入输出参数

函数参数默认是常量。如果需要函数能够修改参数的值,并且在调用结束时这些修改仍然存在,就应该把这个参数定义为输入输出参数(In-Out Parameters)。

在参数定义前添加 inout 关键字来定义输入输出参数,只能传递变量给输入输出参数,并且输入输出参数不能有默认值。

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    ……
}

函数类型

每个函数都有种特定的函数类型,函数的类型由函数的参数类型和返回类型组成。

func addTwoInts(_ a: Int, _ b: Int) -> Int {
    return a + b
}
func printHelloWorld() {
    print("hello, world")
}

函数 addTwoInts 的类型为 (Int, Int) -> Int。函数 printHelloWorld 既没有参数也没有返回值,它的类型为 ()-> Void,或者叫“没有参数,并返回 Void 类型的函数”。

使用函数类型

可以定义一个类型为函数的常量或变量,并将适当的函数赋值给它:

var func1: (Int, Int) -> Int = func2

func1 与 func2 须有相同的函数的类型。

  • 可以用函数类型作为另一个函数的参数类型。
  • 可以用函数类型作为另一个函数的返回类型。

嵌套函数

把函数定义在别的函数体中,称作 嵌套函数(nested functions)。

默认情况下,嵌套函数是对外界不可见的,但是可以被它们的外围函数(enclosing function)调用。一个外围函数也可以返回它的某一个嵌套函数,使得这个函数可以在其他域中被使用。

#EOF