原文: https://www.programiz.com/swift-programming/function-parameter-return-values
在本文中,您将学习不同的用户定义函数,这些函数将通过示例获取不同类型的输入并返回输出。
在上一篇文章 Swift Functions 中,我们了解了函数。 现在,我们将探讨在 Swift 中创建函数的不同方式和类型,即在函数中处理输入和输出。
没有参数且没有返回值的函数
这些类型的函数不接受任何输入和返回值。
func funcname() {//statements}ORfunc funcname() -> () {//statements}ORfunc funcname() -> Void {//statements}
以上所有语法对于创建不带参数且不返回值的函数都是有效的。
上面的语法func funcname() -> ()也等同于func funcname() -> Void,因为Void只是()的类型别名。 您可以访问 Swift Typealias 了解更多信息。
示例 1:没有传递参数,也没有返回值
func greetUser() {print("Good Morning!")}greetUser()
当您运行上述程序时,输出将是:
Good Morning!
没有参数但返回值的函数
这些类型的函数不接受任何输入参数,而是返回一个值。 要添加返回类型,您需要添加箭头(->)和返回类型。
func funcname() -> ReturnType {//statementsreturn value}
示例 2:没有传递参数但返回值
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) {//statements}
示例 3:传递参数但没有返回值
func greetUser(msg:String) {print(msg)}greetUser(msg: "Good Morning!")
运行该程序时,输出为:
Good Morning!
在上述程序中,该函数接受类型为String的单个参数。 该参数只能在函数内部使用。msg是参数的名称。
您可以通过向函数传递参数名称为greetUser(msg: "Good Morning!")的字符串值来调用该函数。msg参数名称仅在函数greetUser()内部可见。
因此,语句print(msg)输出"Good Morning!"。
具有参数和返回值的函数
这些类型的函数使用参数,还返回值。
func funcname(parameterName:Type) -> ReturnType {//statements}
示例 4:传递参数并返回值
func greetUser(name:String) -> String {return "Good Morning! " + name}let msg = greetUser(name: "Jack")print(msg)
运行该程序时,输出为:
Good Morning! Jack
在上述程序中,该函数接受String类型的单个参数,并且还返回字符串值Good Morning! Jack。
具有多个参数和多个返回值的函数
这些类型的函数采用以逗号分隔的多个参数,并且还返回多个值。 您可以使用元组在 Swift 中返回多个值。 有关更多信息,请参见 Swift 元组。
func funcname(parameterName:Type, parameterName2:Type ,...) -> (ReturnType, ReturnType...) {//statements}
示例 5:传递了多个参数和多个返回值
func greetUser(name:String, age:Int) -> (String, Int) {let msg = "Good Morning!" + namevar userage = ageif 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!JackYou have 0 coins left
在上述程序中,函数greetUser()接受类型为String和Int的多个参数。 该函数还以String和Int类型的元组返回多个值。
要访问每个返回值,我们使用索引位置 0,1… 在这里,我们使用msg.0访问Good Morning!Jack和msg.1访问 0。
有时使用索引位置可能不直观且不可读。 我们可以通过给名称指定返回值来优雅地解决此问题。 上面的程序也可以如下重写。
示例 6:具有名称的多个返回值
func greetUser(name:String, coins:Int) -> (name:String, coins:Int) {let msg = "Good Morning!" + namevar userCoins = coinsif 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 {//statements}
让我们在下面的示例中看到它。
示例 7:不带参数标签的函数
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)
现在,将函数更改为:
示例 8:具有更好的函数调用但不作为参数名称的函数
func sum(of:Int, and:Int) -> Int {return of + and}let result = sum(of: 2, and: 3)print("The sum is \(result)")
现在,方法调用是可表达的。 但是,现在我们必须在return of + and中使用参数名称of和and来找到两个数字的和。 现在,这使得函数体不可读。 在函数体内使用a和b代替of和and。
为此,我们必须将参数标签明确定义为:
示例 9:带有参数标签的函数
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 {//statements}
示例 10:具有默认参数值的函数
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 5The sum is 10The sum is 9The sum is 15
在上述程序中,函数sum(of a :Int = 7 , and b:Int = 8) -> Int接受两个类型为Int的参数,但也指定了参数a = 7和b = 8.的默认值
如果在函数调用中以sum(of: 2, and: 3)的形式将值作为参数传递,则将使用 2 和 3 代替参数默认值。
但是,如果未将参数值传递为sum(),则将默认值 7 和 8 用作参数值。
具有可变参数的函数
可变参数可以接受零个或多个特定类型的值。 您可以通过在参数的类型名称后插入三个句点字符(…)来指定可变参数。
当需要在调用函数时将各种数量的输入值传递给参数时,通常使用可变参数。 例如,数字列表,字母列表等。
具有可变参数的函数的语法为:
func funcname(parameterName:Type...) -> Return Type {//statements}
示例 11:具有可变参数的函数
func sum(of numbers:Int...) {var result = 0for num in numbers {result += num}print("The sum of numbers is \(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 num in numbers值中应用for-in循环。
运行该程序时,输出为:
The sum of numbers is 36
注意:内置print()函数的 Swift 也接受Any类型的可变参数。
Any代表 Swift 中的任何数据类型,例如Int,Float,Double,String等。
具有输入输出参数的函数
定义函数参数时,无法在体内修改函数参数。 因此,它们默认为常量。 让我们在示例中看一下:
func process(name:String) {if name == ""{name = "guest"}}
上面的程序会导致编译时错误,因为您无法更改参数的值。
如果要让函数修改参数的值,则需要将参数定义为输入输出参数。 您可以通过将inout关键字放在参数类型的前面来编写输入/输出参数。
在后台,一个in-out参数具有一个值,该值传递到函数中,由函数修改,然后从函数中传递回以替换原始值。 因此,函数调用中传递的值不能为常数。 您必须将其声明为变量。
具有inout参数的函数的语法为:
func funcname(parameterName:inout Type) -> Return Type {//statements}
示例 12:带有inout参数的函数
func process(name:inout String) {if name == ""{name = "guest"}}var userName = ""process(name: &userName)print(userName)
运行该程序时,输出为:
guest
在上面的程序中,我们声明了一个函数,该函数接受inout参数name,以便可以在函数体内更改/更改参数。
在将参数传递给in-out参数时,必须在变量名称之前直接使用ampersand (&)符号,以便可以通过函数对其进行修改。
