# 函数

Swift 提供了多种定义和调用函数的方式，支持参数、返回值、函数嵌套、可变参数等功能。

#### 1. 函数的基本定义

一个函数可以有参数和返回值，也可以没有。函数的定义使用 `func` 关键字。

{% code title="基本语法：" overflow="wrap" %}

```
func functionName(parameter1: ParameterType1, parameter2: ParameterType2...) -> ReturnType {
       // 函数体
       return returnValue
}
```

{% endcode %}

* `func`关键字用于声明一个函数。
* `functionName`是函数的名称。
* `parameter1`、`parameter2`等是函数的参数，包括参数名和参数类型。
* `ReturnType`是函数的返回类型，如果函数没有返回值，可以使用`Void`或不指定返回类型，函数体中直接使用`return`或不使用`return`语句。

**无参数无返回值的函数**

```swift
func sayHello() {
    print("Hello, World!")
}

sayHello()  // 调用函数，输出：Hello, World!
```

**有参数无返回值的函数**

```swift
func greet(name: String) {
    print("Hello, \(name)!")
}

greet(name: "Alice")  // 输出：Hello, Alice!
```

**有参数有返回值的函数**

```swift
func add(a: Int, b: Int) -> Int {
    return a + b
}

let result = add(a: 5, b: 3)  // 返回 8
print(result)  // 输出：8
```

#### 2. 参数标签与参数名称 —— 具名参数

Swift 的函数允许为参数定义**外部参数标签**和**内部参数名称**，提高可读性。

**外部和内部参数名称**

```swift
func greet(person name: String, from city: String) {
    print("Hello \(name)! How's the weather in \(city)?")
}

greet(person: "Bob", from: "San Francisco")  // 输出：Hello Bob! How's the weather in San Francisco?
```

**省略参数标签**

如果不需要外部参数标签，可以使用 `_` 来省略：

```swift
func multiply(_ a: Int, _ b: Int) -> Int {
    return a * b
}

let product = multiply(3, 4)  // 输出：12
```

#### 3. 默认参数值

Swift 支持为函数的参数提供默认值，当调用函数时可以忽略这些参数。

```swift
func greet(name: String = "Guest") {
    print("Hello, \(name)!")
}

greet()  // 输出：Hello, Guest!
greet(name: "Alice")  // 输出：Hello, Alice!
```

#### 4. 可变参数

可以为函数定义可变参数，允许传递多个相同类型的值。可变参数在类型后面加上 `...`。

```swift
func sum(of numbers: Int...) -> Int {
    return numbers.reduce(0, +)
}

let total = sum(of: 1, 2, 3, 4)  // 输出：10
```

#### 5. 返回多个值（元组）

函数可以通过返回一个元组来返回多个值。

```swift
func minMax(numbers: [Int]) -> (min: Int, max: Int)? {
    if numbers.isEmpty { return nil }
    var currentMin = numbers[0]
    var currentMax = numbers[0]
    for number in numbers {
        if number < currentMin {
            currentMin = number
        } else if number > currentMax {
            currentMax = number
        }
    }
    return (currentMin, currentMax)
}

if let bounds = minMax(numbers: [8, -6, 2, 109, 3, 71]) {
    print("Min: \(bounds.min), Max: \(bounds.max)")
}
```

#### 6. 函数类型

函数本身是一种类型，因此可以将函数作为参数传递给其他函数，或作为函数的返回值。

**将函数作为参数传递**

```swift
func add(_ a: Int, _ b: Int) -> Int {
    return a + b
}

func multiply(_ a: Int, _ b: Int) -> Int {
    return a * b
}

func operate(_ a: Int, _ b: Int, using operation: (Int, Int) -> Int) -> Int {
    return operation(a, b)
}

let sum = operate(4, 2, using: add)  // 输出：6
let product = operate(4, 2, using: multiply)  // 输出：8
```

**函数作为返回值**

```swift
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
}

var currentValue = 3
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
print(moveNearerToZero(currentValue))  // 输出：2
```

#### 7. 嵌套函数

函数中还可以定义其他函数，称为嵌套函数。嵌套函数只能在其外部函数内部使用。

```swift
func chooseGreeting(name: String) -> String {
    func formalGreeting() -> String {
        return "Good evening, \(name)."
    }
    
    func casualGreeting() -> String {
        return "Hi, \(name)!"
    }
    
    return name.count > 5 ? formalGreeting() : casualGreeting()
}

print(chooseGreeting(name: "Alice"))  // 输出：Hi, Alice!
print(chooseGreeting(name: "Alexander"))  // 输出：Good evening, Alexander.
```

#### 8. 函数重载

Swift 支持函数重载，即允许定义多个具有相同名字但参数不同的函数。

```swift
func printValue(_ value: Int) {
    print("Integer value: \(value)")
}

func printValue(_ value: String) {
    print("String value: \(value)")
}

printValue(10)  // 输出：Integer value: 10
printValue("Hello")  // 输出：String value: Hello
```

#### 9. 闭包表达式简化函数

闭包是可以在代码中被传递和捕获的函数。它的语法更简洁。

```swift
let numbers = [1, 2, 3, 4]
let doubledNumbers = numbers.map { $0 * 2 }
print(doubledNumbers)  // 输出：[2, 4, 6, 8]
```

这些内容展示了 Swift 中函数的多样性和灵活性。你可以根据具体需求选择适合的函数形式。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hly-tech.gitbook.io/language/swift/han-shu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
