Swift 函数:从基础语法到高阶用法

1. 引言

函数是 Swift 语言的核心组成部分,它帮助我们组织代码、复用逻辑并提高可读性。无论是简单的计算还是复杂的业务处理,函数都扮演着不可或缺的角色。本文将从基础语法入手,逐步深入到参数、返回值、函数类型、闭包等进阶主题,并通过丰富的代码实例帮助读者全面掌握 Swift 函数的使用。

2. 函数的基本定义与调用

在 Swift 中,使用 func 关键字定义函数。一个最简单的函数不接收任何参数,也不返回任何值。

func sayHello() {
    print("Hello, Swift!")
}

// 调用函数
sayHello()  // 输出:Hello, Swift!

函数名后的小括号用于放置参数列表,即使没有参数也必须保留。调用函数时同样需要写上小括号。

3. 函数参数

3.1 带参数的函数

函数可以接收一个或多个参数,每个参数需要声明名称和类型。

func greet(name: String) {
    print("你好,\(name)!")
}

greet(name: "小明")  // 输出:你好,小明!

3.2 多个参数

func add(a: Int, b: Int) {
    let sum = a + b
    print("\(a) + \(b) = \(sum)")
}

add(a: 3, b: 5)  // 输出:3 + 5 = 8

3.3 参数标签

Swift 允许为参数指定外部标签(调用时使用)和内部名称(函数体内使用)。外部标签让函数调用更具可读性。

func calculateTotal(withBasePrice base: Double, taxRate rate: Double) -> Double {
    return base * (1 + rate)
}

let total = calculateTotal(withBasePrice: 100.0, taxRate: 0.08)
print(total)  // 输出:108.0

如果不需要外部标签,可以使用下划线 _ 省略。

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

let result = multiply(4, 6)
print(result)  // 输出:24

3.4 默认参数值

可以为参数设置默认值,调用时如果省略该参数,则使用默认值。

func makeCoffee(size: String = "中杯", sugar: Int = 2) {
    print("制作一杯\(size),加\(sugar)块糖的咖啡。")
}

makeCoffee()                    // 制作一杯中杯,加2块糖的咖啡。
makeCoffee(size: "大杯")         // 制作一杯大杯,加2块糖的咖啡。
makeCoffee(size: "小杯", sugar: 0) // 制作一杯小杯,加0块糖的咖啡。

4. 返回值

4.1 返回单个值

使用箭头 -> 指定返回值类型,函数体内使用 return 返回结果。

func square(_ number: Int) -> Int {
    return number * number
}

let squared = square(7)
print(squared)  // 输出:49

4.2 返回多个值(元组)

Swift 的元组可以轻松实现返回多个值。

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)
}

let bounds = minMax(array: [8, -6, 2, 109, 3, 71])
print("最小值是 \(bounds.min),最大值是 \(bounds.max)")
// 输出:最小值是 -6,最大值是 109

4.3 可选返回值

当函数可能没有返回值时,可以返回可选类型。

func findIndex(of target: String, in array: [String]) -> Int? {
    for (index, value) in array.enumerated() {
        if value == target {
            return index
        }
    }
    return nil
}

let fruits = ["苹果", "香蕉", "橙子"]
if let index = findIndex(of: "香蕉", in: fruits) {
    print("香蕉的索引是 \(index)")  // 输出:香蕉的索引是 1
} else {
    print("未找到")
}

5. 函数类型与高阶函数

5.1 函数类型

每个函数都有特定的类型,由参数类型和返回值类型组成。函数类型可以作为变量、参数或返回值使用。

func addTwoNumbers(a: Int, b: Int) -> Int {
    return a + b
}

// 声明一个函数类型变量
var mathFunction: (Int, Int) -> Int = addTwoNumbers
let sum = mathFunction(10, 20)
print(sum)  // 输出:30

5.2 函数作为参数

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

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

let result1 = applyOperation(10, 5, operation: add)
let result2 = applyOperation(10, 5, operation: subtract)
print(result1)  // 输出:15
print(result2)  // 输出:5

5.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
}

var currentValue = 3
let moveNearer = chooseStepFunction(backward: currentValue > 0)
while currentValue != 0 {
    print("当前值:\(currentValue)")
    currentValue = moveNearer(currentValue)
}
// 输出:当前值:3、2、1

6. 闭包

6.1 闭包表达式

闭包是自包含的函数代码块,可以捕获并存储其所在上下文中的变量和常量。Swift 提供了简洁的闭包语法。

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

// 使用函数排序
func backward(_ s1: String, _ s2: String) -> Bool {
    return s1 > s2
}
var reversedNames = names.sorted(by: backward)

// 使用闭包表达式
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
    return s1 > s2
})

// 简写:省略类型
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 })

// 简写:省略 return
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 })

// 简写:使用参数名缩写
reversedNames = names.sorted(by: { $0 > $1 })

// 简写:使用运算符
reversedNames = names.sorted(by: >)
print(reversedNames)  // 输出:["Ewa", "Daniella", "Chris", "Barry", "Alex"]

6.2 尾随闭包

当闭包是函数的最后一个参数时,可以将其写在函数调用的小括号之外,使代码更清晰。

func performRequest(url: String, completion: (Bool) -> Void) {
    // 模拟网络请求
    let success = true
    completion(success)
}

// 不使用尾随闭包
performRequest(url: "https://example.com", completion: { success in
    print("请求成功:\(success)")
})

// 使用尾随闭包
performRequest(url: "https://example.com") { success in
    print("请求成功:\(success)")
}

6.3 捕获值

闭包可以捕获其定义时所在作用域中的变量和常量,即使这些变量在闭包定义后发生变化,闭包内捕获的值也会同步更新。

func makeIncrementer(incrementAmount: Int) -> () -> Int {
    var total = 0
    func incrementer() -> Int {
        total += incrementAmount
        return total
    }
    return incrementer
}

let incrementByTen = makeIncrementer(incrementAmount: 10)
print(incrementByTen())  // 输出:10
print(incrementByTen())  // 输出:20
print(incrementByTen())  // 输出:30

7. 可变参数与 inout 参数

7.1 可变参数

可变参数可以接收零个或多个指定类型的值,在函数体内以数组形式访问。

func sum(_ numbers: Int...) -> Int {
    var total = 0
    for number in numbers {
        total += number
    }
    return total
}

print(sum(1, 2, 3))        // 输出:6
print(sum(1, 2, 3, 4, 5))  // 输出:15
print(sum())               // 输出:0

7.2 inout 参数

默认情况下,函数参数是常量,无法在函数体内修改。使用 inout 关键字可以修改传入的变量,并将修改结果反映到函数外部。

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

var x = 10
var y = 20
swapTwoInts(&x, &y)
print("x = \(x), y = \(y)")  // 输出:x = 20, y = 10

8. 嵌套函数

函数可以在另一个函数体内定义,这种函数称为嵌套函数。嵌套函数可以访问外部函数的变量,并且可以作为返回值返回。

func chooseOperation(_ symbol: String) -> (Int, Int) -> Int {
    func add(_ a: Int, _ b: Int) -> Int { return a + b }
    func subtract(_ a: Int, _ b: Int) -> Int { return a - b }
    func multiply(_ a: Int, _ b: Int) -> Int { return a * b }
    
    switch symbol {
    case "+":
        return add
    case "-":
        return subtract
    case "*":
        return multiply
    default:
        return add
    }
}

let operation = chooseOperation("*")
let result = operation(6, 7)
print(result)  // 输出:42

9. 实战示例:综合运用

下面通过一个综合示例,将本文介绍的知识点串联起来,实现一个简单的学生成绩管理系统。

// 定义学生结构体
struct Student {
    var name: String
    var scores: [String: Double]
}

// 计算平均分
func averageScore(for student: Student) -> Double {
    let total = student.scores.values.reduce(0, +)
    return total / Double(student.scores.count)
}

// 根据平均分评级
func grade(for average: Double) -> String {
    switch average {
    case 90...100:
        return "优秀"
    case 80..<90:
        return "良好"
    case 60..<80:
        return "及格"
    default:
        return "不及格"
    }
}

// 使用闭包对数组排序
let students = [
    Student(name: "小明", scores: ["数学": 92, "语文": 85, "英语": 88]),
    Student(name: "小红", scores: ["数学": 78, "语文": 90, "英语": 95]),
    Student(name: "小刚", scores: ["数学": 65, "语文": 72, "英语": 58])
]

// 按平均分从高到低排序
let sortedStudents = students.sorted { student1, student2 in
    return averageScore(for: student1) > averageScore(for: student2)
}

// 输出成绩单
for student in sortedStudents {
    let avg = averageScore(for: student)
    print("\(student.name):平均分 \(avg),评级 \(grade(for: avg))")
}
// 输出:
// 小红:平均分 87.66666666666667,评级 良好
// 小明:平均分 88.33333333333333,评级 良好
// 小刚:平均分 65.0,评级 及格

10. 总结

本文系统介绍了 Swift 函数的核心知识,包括基本定义、参数标签、默认参数、返回值、函数类型、闭包、可变参数、inout 参数以及嵌套函数等内容。函数是 Swift 编程的基础,掌握这些知识后,读者可以编写出结构清晰、复用性强的代码。建议读者在 Xcode Playground 中动手实践每一个示例,并尝试组合不同的特性来解决实际问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值