首页 / Swift 编程语言教程 / 函数定义、调用与返回值

Swift 编程语言教程

函数定义、调用与返回值

本教程共 93 篇 · 第 28 篇 · 更新于 2026-08-08 · 约 9 分钟阅读

Swift函数func返回值参数元组返回隐式返回Void

本节目标:能用 func 定义函数、用名字加参数去调用它,并掌握无参数、多参数、无返回值、多返回值和隐式返回这几种形态。

函数是一段“为了完成某件事”而打包好的代码,起个名字,以后想用就直接叫它名字。比如“打招呼”这件事,你不用每次都把打印逻辑写一遍,封装成函数 greet,需要时就 greet(person: "小明")。Swift 的函数语法统一又灵活,从最简单的无参函数到复杂的多参数函数都能优雅表达。

1-1 定义一个函数

定义函数以 func 关键字开头,后面跟函数名、一对括号(里面放参数),再用返回箭头 -> 指向返回类型,最后是花括号里的函数体。

func greet(person: String) -> String {
    let greeting = "你好," + person + "!"
    return greeting
}

这个函数叫 greet,吃一个 String 类型的参数 person,返回一个 Stringreturn greeting 把结果交回去。函数名和参数名一起构成了函数的“签名”,调用时靠它来定位。

Note

函数名用动词或动词短语最直观,比如 greetcalculateTotalprintScore。Swift 鼓励起“读起来像一句话”的名字,调用时才顺口。

1-2 调用一个函数

调用就是写函数名,再把参数按类型传进去。参数要按定义时的顺序一一对应。

print(greet(person: "Anna"))
print(greet(person: "Brian"))

这里把 "Anna" 传给 person,函数返回“你好,Anna!”再交给 print 打印。同一个函数可以反复调用,传不同的值得到不同的结果——这正是函数“复用”的价值。

1-3 没有参数的函数

函数可以不接收任何输入。即便没参数,函数名后面的那对括号也不能省,调用时也要写上空括号。

func sayHelloWorld() -> String {
    return "你好,世界"
}
print(sayHelloWorld())

这种函数适合“每次都产出固定内容”或“内部自己决定一切”的场景。括号的存在是为了和变量名区分开:有括号的是函数调用,没括号的可能是别的。

1-4 多个参数的函数

参数可以有多个,写在括号里用逗号隔开。调用时也按同样顺序、带各自的参数标签传值。

func greet(person: String, alreadyGreeted: Bool) -> String {
    if alreadyGreeted {
        return "又见面了," + person + "!"
    } else {
        return "你好," + person + "!"
    }
}
print(greet(person: "Tim", alreadyGreeted: true))

注意 greet(person:alreadyGreeted:) 和前面的 greet(person:) 是两个不同的函数,虽然名字都含 greet,但参数列表不同。Swift 靠“函数名 + 参数标签”整体来区分函数,这点后面讲重载时还会细说。

1-5 没有返回值的函数

函数也可以不返回东西。这时省略返回箭头和返回类型即可。

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

严格说,这种函数其实也“返回”了一个特殊类型 Void(就是空元组 ()),只是你通常不用管它。Swift 让你省略,是为了让“只做事、不生产结果”的函数写起来更轻。

Warning

一个声明了返回类型的函数,必须保证每条路径都能 return 出值。如果某条路径走到函数末尾还没 return,编译器会报错。反过来,没声明返回类型的函数,写 return 也行,只是它返回的是 Void

返回值还能被调用者忽略。比如一个“打印并返回字符数”的函数,你可以只调用不接收它的返回值:

func printAndCount(string: String) -> Int {
    print(string)
    return string.count
}
func printWithoutCounting(string: String) {
    let _ = printAndCount(string: string)
}
printAndCount(string: "你好,世界")   // 打印并返回 5
printWithoutCounting(string: "你好,世界")  // 只打印

1-6 用元组返回多个值

有时一个函数想一次给你好几个结果,比如“找出最大和最小”。让返回类型是一个元组,就能把多个值打包带回。

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

返回类型 (min: Int, max: Int) 给元组的每个成员起了名字,调用时就能用点语法 bounds.min 取出来,比用下标 bounds.0 清楚得多。元组成员的名字在返回类型里定好,返回那行甚至不用再写名字。

Tip

如果传入的数组可能为空,上面的写法会在 array[0] 处崩溃。真实代码里应该让返回类型变成可选元组 (min: Int, max: Int)?,空数组时返回 nil。可选元组 (Int, Int)? 和成员是可选的元组 (Int?, Int?) 不是一回事——前者是整个元组可能没有,后者是元组一定有、但某个成员可能没值。

1-7 隐式返回

当函数体只有一行表达式时,Swift 允许省略 return,那行表达式的值自动成为返回值。

func greeting(for person: String) -> String {
    "你好," + person + "!"
}
print(greeting(for: "Dave"))

整个函数体就是那句字符串拼接,所以它就是返回值。这种“单行隐式返回”让小函数特别干净。但要注意:函数体必须真的只有那一行,多行就不适用了。

Note

隐式返回值也得是个有值的东西。你不能把 print(13) 当隐式返回——print 返回 Void,编译器不接受。但像 fatalError("出错") 这种“永远不返回”的函数可以当隐式返回,因为 Swift 知道代码根本到不了那一步。

1-8 给初学者的函数心智模型

把函数想象成一台小机器最直观:机器上有几个“进料口”(参数),你投进去原料,机器内部按固定流程加工(函数体),最后从“出料口”吐出成品(返回值)。参数类型就是进料口的形状,塞错形状的原料机器不收;返回类型就是出料口的形状,你拿到手的东西一定是这个类型。

这种“机器思维”能帮你避开两个误区。一是以为函数必须返回东西——很多机器只干活不产成品(比如打印日志),那是没出料口的机器,完全合法。二是混淆“纯函数”和“有副作用的函数”:纯函数只靠输入算输出、不改任何外部状态;有副作用的函数会改外部变量、打印、写文件。两者都常见,关键是心里清楚你写的是哪种。

1-9 先写后改,别追求一次完美

初学函数别追求一次写完美。先把功能跑通——哪怕参数名粗糙、没有返回值——再回头补参数标签、拆小函数、加多返回值。能跑的函数胜过漂亮的空壳。

等你写顺了,会自然形成习惯:先想清楚“这个函数吃啥、产啥”,再动笔。输入输出边界定得清,函数就不会越写越胖。这章打下的“定义—调用—返回”三步,是后面所有函数玩法的地基。

函数把“输入、处理、输出”三段式表达得清清楚楚。下一章我们深入参数:每个参数其实有两套名字——给调用者看的“参数标签”和给函数体看的“参数名”,搞懂它函数读起来才像自然语言。