在本文中,您将学习不同的用户定义函数,这些函数将通过示例获取不同类型的输入并返回输出。
在上一篇文章Swift 函数中,我们了解了函数。现在,我们将探讨在Swift中创建函数的不同方式和类型,即在函数中处理输入和输出。
这些类型的函数不接受任何输入和返回值。
func funcname() { //语句 } 或者 func funcname() -> () { //语句 } 或者 func funcname() -> Void { //语句 }
以上所有语法对于创建不带参数且不返回值的函数都是有效的。
上面的语法func funcname()->()也等同于func funcname()->void,因为void只是()的一个类型别名。您可以访问Swift 类型别名来了解更多信息。
func greetUser() { print("Good Morning!") } greetUser()
当您运行上述程序时,输出将是:
Good Morning!
这些类型的函数不接受任何输入参数,而是返回一个值。要添加返回类型,您需要添加箭头(->)和返回类型。
func funcname() -> ReturnType { //语句 return value }
func greetUser() -> String { return "Good Morning!" } let msg = greetUser() print(msg)
当您运行上述程序时,输出将是:
Good Morning!
在上面的程序中,您将返回类型定义为String。现在,该语句必须从函数内部的语句中返回一个字符串,否则您将抛出错误。
return 关键字将程序的控制权从函数主体转移到函数调用。如果需要从函数返回值,请在 return 关键字后面添加要返回的值。
return "Good Morning!" 语句从函数返回String 类型的值。请注意,返回值的类型和值必须匹配。
您还可以将返回值分配给变量或常量。let msg = 将返回值分配给常量 msg。因此该语句 print(msg )输出“Good Morning!”。
如果您想忽略该值,则只需使用下划线 _ ,即 let _ =。
参数用于在函数中输入。参数包含参数名称和类型,后跟冒号(:)。这些类型的函数采用输入参数,但不返回值。
func funcname(parameterName:Type) { //语句 }
func greetUser(msg:String) { print(msg) } greetUser(msg: "Good Morning!")
当您运行上述程序时,输出将是:
Good Morning!
在上述程序中,该函数接受字符串类型的单个参数。该参数只能在函数内部使用。msg是参数的名称。
您可以通过向函数传递参数名称为 msg 的字符串值来调用函数 greetUser(msg: "Good Morning!")。该参数名称只在 greetUser() 函数内部可见。
因此,print(msg)语句输出 “Good Morning!”。
这些类型的函数使用参数并返回值。
func funcname(parameterName:Type) -> ReturnType { //语句 }
func greetUser(name:String) -> String { return "Good Morning! " + name } let msg = greetUser(name: "Jack") print(msg)
当您运行上述程序时,输出将是:
Good Morning! Jack
在上面的程序中,该函数接受String类型的单个参数,并且还返回String类型的值“Good Morning! Jack”。
这些类型的函数采用以逗号分隔的多个参数,并且还返回多个值。您可以使用元组在Swift中返回多个值。
func funcname(parameterName:Type, parameterName2:Type ,...) -> (ReturnType, ReturnType...) { //语句 }
func greetUser(name:String, age:Int) -> (String, Int) { let msg = "Good Morning!" + name var userage = age if age < 0 { userage = 0 } return (msg, userage) } let msg = greetUser(name: "Jack", age: -2) print(msg.0) print("You have \(msg.1) coins left")
当您运行上述程序时,输出将是:
Good Morning!Jack You have 0 coins left
在以上程序中,该函数greetUser()接受类型为 String和 Int 的多个参数。该函数还返回多个值,类型为String 和 Int。
为了访问每个返回值,我们使用索引位置0,1,…在这里,我们使用 msg.0 访问 “ Good Morning!Jack ”和 msg.1 访问“0”。
使用索引位置有时可能是不直观和不可读的。我们可以通过为返回值命名来优雅地解决这个问题。上面的程序也可以按照下面的方式重写。
func greetUser(name:String, coins:Int) -> (name:String, coins:Int) { let msg = "Good Morning!" + name var userCoins = coins if coins < 0 { userCoins = 0 } return (msg, userCoins) } let msg = greetUser(name: "Jack",coins: -2) print(msg.name) print("You have \(msg.coins) coins left")
在此程序中,返回类型为元组,其中包含具有该类型的变量名称。这样做的主要优点是您可以使用变量名 msg.name和 msg.coins 代替 msg.0和 msg.1 来访问结果。
定义接受输入的函数时,可以在参数名称的帮助下定义输入名称。但是,还有另一种名称可以与参数名称一起使用,称为参数标签。
自变量标签的使用允许以表达方式,类似于句子的方式调用函数,同时仍提供可读且意图明确的函数主体。
每个函数参数都具有参数标签和参数名称。默认情况下,参数使用其参数名称作为其参数标签。但是,如果您明确定义了参数名称,则在调用函数时会使用参数标签。
带参数标签的函数的语法为
func funcname(argumentLabel parameterName:Type)-> Return Type { //语句 }
让我们在下面的示例中看到这一点。
func sum(a:Int, b:Int) -> Int { return a + b } let result = sum(a: 2, b: 3) print("The sum is \(result)")
当您运行上述程序时,输出将是:
The sum is 5
在上面的示例中,我们没有指定参数标签,因此在调用函数时它将使用默认参数名称a和b作为参数标签。
当调用函数时,您可能会注意到函数调用不是表达性的/句子。 如果您可以将函数调用设置为:
let result = sum(of: 2, and: 3)
现在让我们将函数更改为:
func sum(of:Int, and:Int) -> Int { return of + and } let result = sum(of: 2, and: 3) print("The sum is \(result)")
现在,方法调用是可表达的。但是,现在我们必须使用参数名称of& and,return of + and 来查找两个数字的和。现在,这使得函数体可读性较差。在函数体内使用a和b代替of&and将更有意义。
为此,我们必须将参数标签明确定义为:
func sum(of a :Int, and b:Int) -> Int { return a + b } let result = sum(of: 2, and: 3) print("The sum is \(result)")
在上述程序中,该函数接受Int类型的两个参数。函数调用使用参数标签of&and,这在调用函数sum(of: 2, and: 3),而不是 sum(a: 2, b: 3)。
另外,函数主体使用参数名称a和b,而不是of&and,这在应用操作时也更有意义。
您还可以通过在参数名称前写一个下划线 _ 来省略参数标签。
func sum(_ a :Int, _ b:Int) -> Int { return a + b } let result = sum(2, 3) print("The sum is \(result)")
您可以为函数中的任何参数提供默认值,方法是在该参数的类型之后为该参数分配一个值。提供默认参数可以使您在调用函数时忽略该参数。
如果在调用函数时未将值传递给参数,则使用其默认值。但是,如果在调用时将值显式传递给参数,则使用指定的值。
func funcname(parameterName:Type = value) -> Return Type { //语句 }
func sum(of a :Int = 7, and b:Int = 8) -> Int { return a + b } let result1 = sum(of: 2, and: 3) print("The sum is \(result1)") let result2 = sum(of: 2) print("The sum is \(result2)") let result3 = sum(and: 2) print("The sum is \(result3)") let result4 = sum() print("The sum is \(result4)")
当您运行上述程序时,输出将是:
The sum is 5 The sum is 10 The sum is 9 The sum is 15
在上面的程序中,该函数sum(of a :Int = 7 , and b:Int = 8) -> Int接受两个Int类型的参数,并且指定了参数a=7和b=8的默认值。
如果在函数调用中将value作为参数传递,sum(of: 2, and: 3) 则使用2和3代替参数默认值。
但是如果您不将参数值作为sum()传递,那么将使用默认值7和8作为参数值。
可变参数可以接受零个或多个特定类型的值。您可以通过在参数的类型名称后插入三个句点字符(...)来指定可变参数。
当需要在调用函数时将各种数量的输入值传递给参数时,通常使用可变参数。例如,数字列表,字母列表等。
具有可变参数的函数的语法为:
func funcname(parameterName:Type...) -> Return Type { //语句 }
func sum(of numbers:Int...) { var result = 0 for num in numbers { result += num } print("数的总和是 \(result)") } sum(of: 1, 2, 3, 4, 5, 6, 7, 8)
在上述程序中,该函数sum(of numbers:Int...)接受Int类型的可变参数。可变参数可以接受多个以逗号分隔的值 sum(of: 1, 2, 3, 4, 5, 6, 7, 8)。
作为可变参数传递的值1、2、3、4、5、6、7、8在函数体内可以作为Int类型数组使用。因此,我们可以将for-in循环应用为for num in numbers。
当您运行上述程序时,输出将是:
数的总和是 36
注意:Swift内置print()函数还接受任意类型的可变参数。
Any表示Swift中的任何数据类型,例如Int、Float、Double、String等。
定义函数参数时,无法在体内修改函数参数。因此,默认情况下它们是常量。让我们在示例中看一下:
func process(name:String) { if name == ""{ name = "guest" } }
上面的程序会导致编译时错误,因为您无法更改参数的值。
如果要让函数修改参数值,则需要将参数定义为 in-out 参数。您可以通过将 inout 关键字放在参数类型的前面来编写输入/输出参数。
在后台,一个in-out参数具有一个值,该值传递到函数中,由函数修改,然后从函数中传递回以替换原始值。因此,函数调用中传递的值不能为常量。您必须将其声明为变量。
具有inout参数的函数的语法为:
func funcname(parameterName:inout Type) -> Return Type { //语句 }
func process(name:inout String) { if name == ""{ name = "guest" } } var userName = "" process(name: &userName) print(userName)
当您运行上述程序时,输出将是:
guest
在上面的程序中,我们声明了一个接受inout参数的函数,以便可以在函数体内更改/更改参数 name。
在将参数传递给in-out参数时,必须在变量名前直接使用&号,以便函数可以修改它。