上一章Swift教程请查看:swift定义和调用函数
在本文中,你将通过示例了解不同的用户定义函数,这些函数接受不同类型的输入并返回输出。
在前一篇文章Swift函数中,我们学习了函数。现在,我们来看看在Swift中创建一个函数的不同方法和类型,也就是在一个函数中处理输入和输出。
没有参数也没有返回值的函数
这些类型的函数不接受任何输入和返回值。
func funcname() {
//statements
}
OR
func funcname() -> () {
//statements
}
OR
func funcname() -> Void {
//statements
}
以上所有语法对于创建不接受参数且不返回值的函数都是有效的。
上面的语法func
funcname() ->()也等价于func funcname() -> Void,因为Void只是()的一个类型别名。
示例1:没有传递参数,也没有返回值的函数
func greetUser() {
print("Good Morning!")
}
greetUser()
函数没有参数只有返回值的函数
这些类型的函数不接受任何输入参数,而是返回一个值。要添加返回类型,你需要添加箭头(->)和返回类型。
func funcname() -> ReturnType {
//statements
return value
}
例2:没有传递参数,但是返回值的函数
func greetUser() -> String {
return "Good Morning!"
}
let msg = greetUser()
print(msg)
在上面的程序中,你已经将返回类型定义为String,现在,该语句必须从函数内部的语句返回一个字符串,否则将得到一个错误。
return关键字将程序的控制权从函数体转移到函数调用,如果需要从函数返回值,请在return关键字后添加值。
语句从函数中返回类型为String的值,注意,返回的类型和值必须匹配。
你还可以将返回值分配给变量或常量,让msg =将返回值赋给常量msg,因此,语句打印(msg)输出到控制台。
如果你想忽略这个值,你可以简单地使用_ 如 let _ =。
带有参数但没有返回值的函数
参数用于获取函数的输入,该参数包含一个参数名称和类型,后跟一个冒号(:),这些类型的函数接受输入参数,但不返回值。
func funcname(parameterName:Type) {
//statements
}
示例3,传递参数但没有返回值的函数
func greetUser(msg:String) {
print(msg)
}
greetUser(msg: "Good Morning!")
在上面的程序中,函数接受一个String类型的参数,参数只能在函数内部使用,msg是参数的名称。
你可以通过传递参数名为greetUser的字符串值来调用该函数(msg:“”),msg参数名只在函数greetUser()中可见。
带有参数和返回值的函数
这些类型的函数接受参数并返回值。
func funcname(parameterName:Type) -> ReturnType {
//statements
}
示例4:传递参数并返回值
func greetUser(name:String) -> String {
return "Good Morning! " + name
}
let msg = greetUser(name: "Jack")
print(msg)
在上面的程序中,函数接受String类型的单个参数,并返回类型为String的值。
具有多个参数和多个返回值的函数
这些类型的函数接受由逗号分隔的多个参数,并返回多个值,你可以使用元组在Swift中返回多个值。参见Swift元组了解更多信息。
func funcname(parameterName:Type, parameterName2:Type ,...) -> (ReturnType, ReturnType...) {
//statements
}
例5:传递多个参数和多个返回值
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")
在上面的程序中,函数greetUser()接受类型为String和Int的多个参数。
使用索引位置有时是不直观和不可读的,我们可以通过为返回值指定名称来优雅地解决这个问题,上面的程序也可以重写如下。
示例6:多个带名称的返回值
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")
在这个程序中,返回类型是tuple,它包含带有类型的变量名。这样做的主要好处是可以使用变量名作为msg.name和msg访问结果。
带参数标签的函数
在定义接受输入的函数时,可以在参数名的帮助下定义输入名。但是,还有另一种类型的名称可以与参数名称一起提供,称为参数标签。
参数标签的使用允许以一种富有表现力的方式调用一个函数,类似于句子的方式,同时仍然提供一个可读的、意图清晰的函数体。
每个函数参数都有一个参数标签和一个参数名。默认情况下,参数使用它们的参数名作为参数标签。但是,如果显式定义了参数名,则在调用函数时将使用参数标签。
带参数标签的函数的语法是
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)")
在上面的例子中,我们没有指定参数标签,所以它在调用函数时使用默认的参数名a和b作为参数标签。
在调用函数时,你可能会注意到函数调用不是表达式/语句,如果你可以使函数调用如下:
现在我们把函数改为:
例8:函数具有更好的函数调用,但不作为参数名
func sum(of:Int, and:Int) -> Int {
return of + and
}
let result = sum(of: 2, and: 3)
print("The sum is \(result)")
现在这个方法调用很有表现力。但是,现在我们必须使用参数名&和作为+的返回,并找到两个数字的和,这使得函数体不可读,在函数体中使用a和b而不是of&d会更有意义。
为此,我们必须明确定义参数标签为:
例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类型的参数,函数调用使用&和的参数标签,这在调用函数sum(of: 2, and: 3)而不是sum(a: 2, b: 3)时是有意义的。
另外,函数体使用参数名a和b而不是&,这在应用操作时也更有意义。
你还可以通过在参数名之前写入_来省略参数标签。
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)")
在上面的程序中,函数sum(a:Int
= 7, 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 = 0
for num in numbers {
result += num
}
print("The sum of numbers is \(result)")
}
sum(of: 1, 2, 3, 4, 5, 6, 7, 8)
在上面的程序中,函数sum(number:Int…)接受一个类型为Int的可变参数,可变参数可以接受多个以逗号分隔的值作为和(1、2、3、4、5、6、7、8)。
作为可变参数传递的值1、2、3、4、5、6、7、8在函数体中作为Int类型的数组可用。因此,我们可以对数值中的num应用for-in循环。
注:Swift内置print()函数也接受任意类型的可变参数。
任何表示在Swift中的任何数据类型,如Int, Float, Double,String等。
带有输入-输出参数的函数
在定义函数参数时,不能在主体中修改函数参数,它们是默认的常数。让我们看看这个例子:
func process(name:String) {
if name == ""{
name = "guest"
}
}
上面的程序会导致编译时错误,因为你无法更改参数的值。
如果希望函数修改参数的值,需要将参数定义为in-out参数。通过在参数的类型前放置inout关键字,可以编写in-out参数。
在后台,in-out参数有一个值,该值被传递到函数中,由函数修改,然后传递回函数,以替换原始值。因此,函数调用中传递的值不能是常量。你必须将它声明为一个变量。
inout参数函数的语法为
func funcname(parameterName:inout Type) -> Return Type {
//statements
}
例12:带in out参数的函数
func process(name:inout String) {
if name == ""{
name = "guest"
}
}
var userName = ""
process(name: &userName)
print(userName)
在上面的程序中,我们声明了一个接受inout参数名的函数,这样就可以在函数体中更改参数。
在将参数传递给in-out参数时,必须在变量名前直接使用&符号,以便函数可以修改它。