100 Days of Swift 学习笔记:Day8 函数进阶!默认参数与错误处理,让函数更健壮
Day8 聚焦 Swift 函数的 “进阶功能”—— 默认参数让函数调用更简洁,错误处理则让函数在异常场景下更稳定。这两个功能是从 “写能用的函数” 到 “写好用、健壮的函数” 的关键,比如给乘法表函数加默认结束值,不用每次都传相同参数;给密码检查函数加错误处理,避免因密码不合法导致后续逻辑崩溃。整理了实操代码、避坑点和应用场景,新手朋友跟着练能快速提升函数设计能力~
目录
2. 第二步:函数抛出错误(用 throws 和 throw)
一、默认参数:给参数设 “默认值”,减少重复传参
很多时候函数的某个参数 “大部分场景下都用同一个值”(比如乘法表默认数到 12、接口请求默认超时时间 3 秒),这时给参数设默认值,调用时可传可不传,代码更简洁。
1. 基础用法:给参数加默认值
// 定义函数:参数名: 类型 = 默认值
func printTimesTable(for number: Int, end: Int = 10) {
for i in 1...end {
print("\(i) x \(number) is \(i * number)")
}
}
// 调用方式1:不传默认参数(用默认值 10)
printTimesTable(for: 5) // 打印 5 的 1-10 乘法表
// 调用方式2:传默认参数(覆盖默认值)
printTimesTable(for: 5, end: 5) // 打印 5 的 1-5 乘法表
- 关键语法:在参数类型后加
= 默认值(比如end: Int = 10),默认值必须是该类型的合法值(不能给Int类型设"abc"当默认值)。 - 优势:兼顾 “灵活性” 和 “简洁性”—— 常规场景不用传默认参数,特殊场景传值覆盖,避免每次调用都写重复的参数(比如
end: 10)。
2. 注意事项:默认参数的顺序
如果函数有多个参数,建议把 “默认参数” 放在后面,避免调用时混淆:
// 推荐:默认参数放后面
func requestData(url: String, timeout: Int = 3) {
print("请求 URL:\(url),超时时间:\(timeout)秒")
}
// 不推荐:默认参数放前面(调用时容易漏传非默认参数)
// func requestData(timeout: Int = 3, url: String) { ... }
// 调用推荐写法的函数,清晰无歧义
requestData(url: "https://example.com") // 用默认超时 3 秒
requestData(url: "https://example.com", timeout: 5) // 覆盖超时为 5 秒
二、错误处理:让函数 “优雅处理异常”,避免崩溃
实际开发中函数常会遇到 “异常场景”(比如密码太短、文件不存在、网络请求失败),如果不处理这些错误,函数会直接崩溃。Swift 的错误处理机制能让我们 “提前定义可能的错误”“在函数中抛出错误”“在调用时捕获并处理错误”,让代码更健壮。
错误处理分三步:定义错误类型 → 函数抛出错误 → 调用时捕获错误。
1. 第一步:定义错误类型(枚举遵循 Error 协议)
用枚举定义 “可能发生的错误”,每个枚举值对应一种错误场景,枚举必须遵循 Swift 内置的 Error 协议(只需声明,不用实现任何方法):
// 定义密码相关的错误类型
enum PasswordError: Error {
case short // 密码太短
case obvious // 密码太简单(比如 12345)
}
- 作用:明确告诉使用者 “这个函数可能会因为哪些原因失败”,比如密码检查函数可能因为 “太短” 或 “太简单” 抛出错误。
2. 第二步:函数抛出错误(用 throws 和 throw)
在函数返回类型前加 throws,标记 “这个函数可能抛出错误”;在异常场景下用 throw 抛出具体的错误(抛出后函数会立即终止,不执行后续代码):
// 定义密码检查函数:throws 标记可能抛错,返回密码评级字符串
func checkPassword(_ password: String) throws -> String {
// 场景1:密码长度小于5,抛出 short 错误
if password.count < 5 {
throw PasswordError.short // 抛出错误,函数终止
}
// 场景2:密码是 12345,抛出 obvious 错误
if password == "12345" {
throw PasswordError.obvious // 抛出错误,函数终止
}
// 没有抛出错误,正常返回评级
if password.count < 8 {
return "OK"
} else if password.count < 10 {
return "Good"
} else {
return "Excellent"
}
}
- 关键语法:
throws:放在函数参数列表和返回类型之间((参数) throws -> 返回类型),告诉 Swift 这个函数可能抛错;throw:在异常场景下调用,抛出具体的错误值(比如throw PasswordError.short),抛出后函数会立即退出,不会执行后面的return。
- 注意:
throws只是 “标记可能抛错”,不是 “必须抛错”—— 如果密码合法,函数会正常返回评级。
3. 第三步:调用函数并捕获错误(do-catch 语句)
调用标记了 throws 的函数时,必须用 try 关键字(告诉 Swift “这里可能抛错”),并放在 do 块中,用 catch 块捕获并处理错误:
do {
// 用 try 调用可能抛错的函数,结果存入 result
let result = try checkPassword("123556346")
// 没有抛错时执行这里
print("Password rating: \(result)") // 输出 Password rating: Good
} catch PasswordError.short {
// 捕获 short 错误,处理逻辑
print("It's so short!")
} catch PasswordError.obvious {
// 捕获 obvious 错误,处理逻辑
print("It's so obvious!")
} catch {
// 捕获其他未明确列出的错误(兜底)
print("There's an error! Details: \(error.localizedDescription)")
}
- 关键结构:
do:包裹 “可能抛错的代码”,里面调用try 函数();catch 错误类型.错误值:捕获特定类型的错误,执行对应处理逻辑;- 最后一个
catch:兜底,捕获所有未明确处理的错误(必须有,避免遗漏); error.localizedDescription:获取错误的本地化描述(通常是英文,实际开发中可自定义错误信息)。
4. 实战场景:处理不同错误的不同逻辑
比如在登录场景中,根据密码错误类型给用户不同的提示:
let userPassword = "1234" // 假设用户输入的密码
do {
let rating = try checkPassword(userPassword)
print("密码合格,评级:\(rating),可继续登录")
} catch PasswordError.short {
print("❌ 密码太短啦!至少需要5个字符") // 针对 short 错误的提示
} catch PasswordError.obvious {
print("❌ 密码太简单啦!不要用 12345 这种哦") // 针对 obvious 错误的提示
} catch {
print("❌ 密码检查失败:\(error)") // 其他错误的兜底提示
}
// 输出:❌ 密码太短啦!至少需要5个字符
三、Day8 学习总结:两个进阶功能的核心价值
| 功能 | 核心作用 | 适用场景 | 关键语法 / 结构 |
|---|---|---|---|
| 默认参数 | 减少重复传参,兼顾灵活性与简洁性 | 参数大部分场景用固定值(如乘法表默认数到 10、接口默认超时 3 秒) | 参数名: 类型 = 默认值 |
| 错误处理 | 优雅处理异常场景,避免函数崩溃 | 函数可能因输入不合法、资源缺失等失败(如密码检查、文件读取) | 1. 枚举遵循 Error;2. 函数加 throws;3. do-catch + try |
明日计划
Day9 要学 Swift 的 “可选类型(Optional)”—— 这是 Swift 中非常有特色的概念,能解决 “变量可能没有值” 的问题,和今天的错误处理相辅相成(比如函数返回可选值表示 “可能有结果,也可能没有”)。有一起打卡的朋友吗?评论区可以分享你用 “默认参数 + 错误处理” 写的小函数(比如 “计算两个数的除法,默认保留 2 位小数,除数为 0 时抛错”)~
更多推荐


所有评论(0)