日进一步。

函数

在swift中,函数的调用使用func来进行。例如:

1
2
3
4
5
6
7
8
9
10
func pcourse(){
let course = """
Hello!
Welcome to the zhhooo.com
"""
print(course)

}

pcourse()

注意:

  • 函数名区分大小写。
  • 在一般命名的场合,一个函数名出现多个单词时,通常下一个单词首字母大写以便与更好的阅读。

接受参数

函数可以接收参数来在调用的时候通过不同情况运行出不同的结果。在函数书写时在括号内标注参数名称和类型比如func pcourse(num: Int){},例如:

1
2
3
func square(number: Int) {
print(number * number)
}

当然,在调用的时候需要添加参数:

1
square(number: 8)

其他例子:

1
2
3
4
5
6
7
func square(numbers: [Int]) {
for number in numbers {
let squared = number * number
print("\(number) squared is \(squared).")
}
}
square(numbers: [2, 3, 4])

注意:

  • 接收的参数以常量的形式加入到函数中。

返回值

在Swift中返回值使用->表示。需要在里面使用return告知swift你需要返回哪个值。例如:

1
2
3
4
5
6
func square(number: Int) -> Int {
return number * number
}

let result = square(number: 8)
print(result)

其他例子:

1
2
3
4
5
6
7
8
9
10
func countMultiplesOf10(numbers: [Int]) -> Int {
var result = 0
for number in numbers {
if number % 10 == 0 {
result += 1
}
}
return result
}
countMultiplesOf10(numbers: [5, 10, 15, 20, 25])

注意:

  • 书写有返回值的函数是,一定要考虑极端情况,必须要保证无论何种情况都有返回值。

参数标签(参数名称)

在swift中允许你在外部调用时和内部调用的参数名称不同,例如在外部调用你想用to,在内部调用你想用name,则你在编写函数时所对应的参数名称应该为:to name: String,例如:

1
2
3
func sayHello(to name: String) {
print("Hello, \(name)!")
}

在调用的时候使用to调用:

1
sayHello(to: "Taylor")

其他例子:

1
2
3
4
5
6
7
8
func countDown(from start: Int) {
var current = start
while current >= 0 {
print("\(current)...")
current -= 1
}
}
countDown(from: 10)

省略参数标签(参数名称)

在swift中你可以省略参数标签,例如print("zhhooo.com")是一个省略参数标签的函数。跟for循环类似,同样是使用下划线来进行省略参数。例如:

1
2
3
4
5
func greet(_ person: String) {
print("Hello, \(person)!")
}

greet("Taylor")

注意:推荐还是不要省略参数标签,因为虽然代码变得很整洁,但是会设立一些阅读门槛或歧义。

参数默认值

在swift中函数中的参数可以设置默认值。格式为<参数名>: <类型> = <默认值>,例如:func find(_ do: String,who: String = "ZhangHong"){}

其他例子:

1
2
3
4
5
6
7
func greet(_ person: String, nicely: Bool = true) {
if nicely == true {
print("Hello, \(person)!")
} else {
print("Oh no, it's \(person) again...")
}
}

在调用的时候可以直接调用。也可以设置已经有默认值的参数:

1
2
greet("Taylor")
greet("Taylor", nicely: false)

其他例子:

1
2
3
4
5
6
7
8
func parkCar(_ type: String, automatically: Bool = true) {
if automatically {
print("Nice - my \(type) parked itself!")
} else {
print("I guess I'll have to do it.")
}
}
parkCar("Tesla")

可变参数函数(参数量可变函数)

我们在swift中可以使用print("one","two","three"),print在这里使用的就是参数量可变的参数。我们只需要标记...就可以将参数变成参数量可变的参数了。参数量可变函数对应的多个参数会传递一个数组。可以使用循环来进行遍历。例如:

1
2
3
4
5
6
func square(numbers: Int...) {
for number in numbers {
print("\(number) squared is \(number * number)")
}
}
square(numbers: 1, 2, 3, 4, 5)

注意:
1.可变参数可能为零值,所以我们接收到的数组可能为空。

编写投掷函数(从内部引发函数错误)

有的时候我们需要在函数内部引发函数错误,例如用户在输入一个简单的密码时,我们需要报错而不是保存它。在返回类型之前引发错误使用的是throw。首先我们需要枚举错误类型,错误类型必须使用swift现有的错误类型,例如:

1
2
3
enum PasswordError: Error {
case obvious
}

之后我们可以通过判断和在返回的参数上的throws -> <类型>throw <报错>来报错:

1
2
3
4
5
6
7
func checkPassword(_ password: String) throws -> Bool {
if password == "password" {
throw PasswordError.obvious
}

return true
}

其他例子:

1
2
3
4
5
6
7
8
9
10
11
enum PlayError: Error {
case cheating
case noPlayers
}
func playGame(name: String, cheat: Bool = false) throws {
if cheat {
throw PlayError.cheating
} else {
print("Let's play a game of \(name)...")
}
}
1
2
3
4
5
6
7
8
9
10
enum PizzaErrors: Error {
case hasPineapple
}
func makePizza(type: String) throws {
if type != "Hawaiian" {
print("Your pizza will be ready in 10 minutes.")
} else {
throw PizzaErrors.hasPineapple
}
}
1
2
3
4
5
6
7
8
9
10
11
12
enum PrintError: Error {
case invalidCount
}
func printPages(text: String, count: Int) throws {
if count <= 0 {
throw PrintError.invalidCount
} else {
for _ in 1...count {
print("Printing \(text)...")
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
enum BookErrors: Error {
case tooFewPages
case tooManyPages
}
func writeBook(---
title: String, pages: Int) throws {
switch pages {
case 0...50:
throw BookErrors.tooFewPages
case 51...400:
print("Perfect![]I'm going to write \(title)...")
default:
throw BookErrors.tooManyPages
}
}

运行投掷函数(处理引发错误的函数)

在刚刚的函数中可以看到我们编写了一个报错的函数,但是Swift不会直接运行报错的函数。那么我们就需要使用do,try,catch来进行报错判断。do{}中引发的错误会直接导致运行catch{},而运行可能引发错误的函数需要使用try,格式为:do {try <函数>} catch{}。例如:

1
2
3
4
5
6
do {
try checkPassword("password")
print("That password is good!")
} catch {
print("You can't use that password.")
}

变更参数

因为加入函数中的参数是以常量的形式加入进来,有的时候我们需要将一个变量运行在函数中进行改变。我们通常会使用homePlace = function(homePlace)这种方式,我们还可以对这种方式进行简化。swift中有一个inout参数,允许你不通过返回值就可以更改输入的变量。例如:

1
2
3
func doubleInPlace(number: inout Int) {
number *= 2
}

在描述类型之前使用inout,并在调用的时候给予许可变更的标识符&,例如:

1
2
var myNum = 10 
doubleInPlace(number: &myNum)

注意:
不要讲let常量(不可变更的值)作为可变更参数进行传递。

总结

  • 函数使我们可以重复使用代码而无需重复自己。
  • 函数可以接受参数-只需告诉Swift每个参数的类型即可。
  • 函数可以返回值,你只需指定要发送回什么类型。如果要返回几件事,请使用元组。
  • 你可以在内部和外部使用不同的名称作为参数,也可以完全省略外部名称。
  • 参数可以具有默认值,这可以在特定值常见时帮助你减少代码编写。
  • 可变参数函数接受零个或多个特定参数,而Swift将输入转换为数组。
  • 函数会引发错误,但是你必须使用调用它们,并使用来try处理错误catch。
  • 你可以inout用来更改函数中的变量,但是通常最好返回一个新值。

参考资料

查看下一天的SwiftUI学习笔记

关于100days英文课程