swift中的函数类型

https://nshipster.com/callable/

函数类型在 swift 中是一等公民,意味着其可以赋值给变量、作为属性存储、作为参数传递或者作为函数返回值。

与其他类型的区别在于函数类型是可以被调用的,你可以调用它来产生一个新的值。

闭包(Closure)

swift 的基础函数类型是闭包(closure), 一个独立的功能单元。

1
let square: (Int) -> Int = { x in x * x }

作为函数类型,你可以在括号内部传递必要数量的参数来调用闭包。

1
square(4) // 16

闭包之所以称为闭包,是因为他是闭合的并且从定义它的上下文中捕获对变量的引用。然而,捕获语义不总是可取的,这样是为什么 swift 提供了一种称为 function 的特殊闭包语法。

函数(Function)

函数是定义在顶级/全局范围内的命名闭包,不捕获任何值。在 swift 中,使用 func 关键字来定义。

1
2
func square(_ x: Int) -> Int { x * x }
square(4) // 16

跟闭包相比,函数在传递参数方面具有更大的灵活性。

函数的参数可以有命名的标签,而不是闭包未标记的位置参数,这对澄清代码在其调用位置的作用大有帮助。

1
2
3
4
func deposit(amount: Decimal,
from source: Account,
to destination: Account) throws { ... }
try deposit(ammount: 1000.00, from: checking, to: savings)

函数可以是泛型的,可以将其用于多种类型的参数:

1
2
3
4
5
6
7
8
func square<T: Numeric>(_ x: T) -> T { x * x }
func increment<T: Numeric>(_ x: T) -> T { x + 1 }
func compose<T>(_ f: @escaping (T) -> T, _ g: @escaping (T) -> T) -> (T) -> T {
{ x in g(f(x)) }
}

compose(increment, square)(4 as Int) // 25 ((4 + 1)²)
compose(increment, square)(4.2 as Double) // 27.04 ((4.2 + 1)²)

函数还可以接收可变参数、自动闭包和默认参数(允许魔术表达式字面量如#function、#file):

1
2
3
4
5
func print(items: Any...) { ... }
func assert(_ condition: @autoclosure () -> Bool,
_ message: @autoclosure () -> String = String(),
file: StaticString = #file,
line: UInt = #line) { ... }

尽管函数在接受参数方面具有灵活性,但我们遇到的大多数函数都是在隐式变量 self 上运行的。这些函数称为方法(Method)。

方法(Method)

方法是一个类型所拥有的函数,方法自动提供对 self 的访问,从而使它们可以有效地捕获被称为隐式参数的实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
struct Queue<Element> {
private var elements: [Element] = []

mutating func push(_ newElement: Element) {
self.elements.append(newElement)
}

mutating func pop() -> Element? {
guard !self.elements.isEmpty else { return nil }
return self.elements.removeFirst()
}

}

Swift 允许在访问成员时省略 self,使得本来已经隐藏的 self 隐藏的更深。